c++ - 重新排序和 memory_order_relaxed

标签 c++ multithreading c++11 atomic memory-model

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.

然后解释说,xy 初始为零,此示例代码

// 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. 尽管 A 在线程 1 中先于 B,而 C 在线程 2 中先于 D,
  2. 没有什么能阻止 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/

相关文章:

c++ - 检查进程是否正在运行 - Windows

c++ - 为什么我不能将比较器放在节点内?

multithreading - RabbitMQ 消费者中的并发消息处理

c# - 为什么 PLinq 不支持超过 63 个并行线程?

c++ - 矩阵的行、列和对角线之和

c++ - 在 boost::asio::serial_port 上解锁同步读取

c++ - 简单的 openGL 程序无法通过编译

c# - 在IEnumerable实现中使用任务并行库实现速度提升

c++ - 使用 boost::optional 制作可选的 std::function 参数

c++ - 提供 `std::complex` 时如何避免嵌入 `T=std::complex<Q>` ?