Cppreference дает following example о memory_order_relaxed
:и изменение порядка memory_order_relaxed
атомарные операции с тегами
memory_order_relaxed
не Синхронизация операции, они не приказывают памяти. Они гарантируют только атомарность и согласованность порядка модификации.
Затем объясняет, что, с x
и y
первоначально нулевым, этот пример кода
// Thread 1:
r1 = y.load(memory_order_relaxed); // A
x.store(r1, memory_order_relaxed); // B
// Thread 2:
r2 = x.load(memory_order_relaxed); // C
y.store(42, memory_order_relaxed); // D
разрешено производить r1 == r2 == 42
, потому что:
- Хотя А секвенировали-перед тем В пределах нить 1 и C - с последовательностью до D в резьбе 2,
- Ничто не мешает D появляться до А в порядке модификации
y
, а B - до C в порядке модификацииx
.
Теперь мой вопрос: если А и В не могут быть перераспределены в пределах потока 1 и, аналогично, С и D в пределах резьбы 2 (так как каждый из них является секвенировали-перед тем в пределах своей нити), не являются точками 1 и 2 в противоречии? Другими словами, без переупорядочения (как кажется, как указано в пункте 1), как возможен сценарий в пункте 2, представленный ниже?
Т1 Т2 ...........
.............. Д (у)
А (у)
в (х)
.............. с (х)
Поскольку в данном случае C бы не быть секвенировали-D, прежде чем нити в пределах 2 , как точка 1.
Я бы порекомендовал посмотреть здесь: http://stackoverflow.com/questions/6319146/c11-introduced-a-standardized-memory-model-what-does-it-mean-and-how-is-it- g, особенно ответ об аналогии со специальной теорией относительности. Мое понимание этого заключается в том, что с расслабленным атомом, нет ничего как глобального времени, поэтому вы не можете просто визуализировать действия в некоторой глобальной диаграмме времени. В частности, каждый поток может иметь в определенный момент другой вид памяти. –