Текущий C++ 0x проектирует состояния на разделе 29.3.9 и 29.3.10, страницы 1111-1112 что в следующем примере:
// Thread 1
r1 = y.load(memory_order_relaxed);
x.store(1, memory_order_relaxed);
// Thread 2
r2 = x.load(memory_order_relaxed);
y.store(1, memory_order_relaxed);
Результат r1 = r2 = 1
возможно, так как операции каждого потока ослабляются и к несвязанным адресам. Теперь мой вопрос о возможных результатах следующего (подобного) примера:
// Thread 1
r1 = y.load(memory_order_acquire);
x.store(1, memory_order_release);
// Thread 2
r2 = x.load(memory_order_acquire);
y.store(1, memory_order_release);
Я думаю это в этом случае результат r1 = r2 = 1
не возможно. Если бы это было возможно, то загрузка y синхронизировалась бы - с (таким образом происходят - прежде), хранилище к y. Подобный x, загрузка x произошла бы - перед хранилищем к x. Но загрузка y упорядочивается прежде (таким образом также происходит - прежде), хранилище к x. Это создает циклическое, происходит - перед отношением, которое я думаю, не позволяется.
Если мы потратим время (или, если хотите, последовательность инструкций) вниз, как при чтении кода, тогда Насколько я понимаю,
Другими словами, если у вас есть код вроде
acquire
// other stuff
release
, то доступ к памяти может перемещаться извне пары получение / выпуск внутрь, но не наоборот (и они также не могут полностью пропускать пару получение / выпуск. ).
С ослабленной семантикой согласованности в вашем первом примере в вопросе оборудование может переупорядочить доступ к памяти так, чтобы хранилища попадали в систему памяти до загрузки, что позволяет r1 = r2 = 1. С семантикой получения / выпуска во втором примере такое переупорядочение предотвращается, и поэтому r1 = r2 = 1 невозможно.