Cppreference 给出 following example关于memory_order_relaxed
:
Atomic operations tagged
memory_order_relaxed
are not synchronization operations, they do not order memory. They only guarantee atomicity and modification order consistency.
然后解释说,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
因为:
- 尽管 A 在线程 1 中先于 B,而 C 在线程 2 中先于 D,
- 没有什么能阻止 D 在
y
的修改顺序中出现在 A 之前,并且 B 在x
的修改顺序中出现在 C 之前。
现在我的问题是:如果 A 和 B 不能在线程 1 中重新排序,同样地,C 和 D 在线程 2 中不能重新排序(因为它们中的每一个都在其线程中先序) , 第 1 点和第 2 点不矛盾吗?换句话说,没有重新排序(正如第 1 点似乎需要的那样),第 2 点中的场景(如下图所示)如何实现?
T1 ............ T2
............ D(y)
A(y)
B(x)
............ C(x)
因为在这种情况下,C 将不会在线程 2 中先于 D,正如第 1 点所要求的那样。
最佳答案
with no reordering (as point 1 seems to require)
第 1 点并不意味着“不重新排序”。它意味着执行线程内的事件排序。编译器将在 B 之前发出 A 的 CPU 指令,在 D 之前发出 C 的 CPU 指令(尽管即使这可能会被 as-if 规则颠覆),但 CPU 没有义务按该顺序执行它们,缓存/写入缓冲区/失效队列没有义务按该顺序传播它们,内存也没有义务保持一致。
(尽管个别架构可能会提供这些保证)
关于c++ - 重新排序和 memory_order_relaxed,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35648936/