放宽原子规则的(轻微)区别是什么?

tow*_*owi 2 c++ memory-model memory-barriers stdatomic relaxed-atomics

在看到 Herb Sutters关于“原子武器”的精彩演讲后,我对放松原子的例子感到有些困惑。

我认为C++ 内存模型(SC-DRF = Sequentially Consistent for Data Race Free)中的原子在加载/读取时执行“获取”。

我知道对于负载 [和存储] 是默认值std::memory_order_seq_cst,因此两者是相同的:

myatomic.load();                          // (1)
myatomic.load(std::memory_order_seq_cst); // (2)
Run Code Online (Sandbox Code Playgroud)

到目前为止一切都很好,没有涉及放松的原子(在听完演讲后,我永远不会使用放松的原子。永远。承诺。但当有人问我时,我可能不得不解释......)。

但是为什么我使用时它是“宽松”的语义

myatomic.load(std::memory_order_acquire);   // (3)
Run Code Online (Sandbox Code Playgroud)

既然负载获取不是释放,为什么这与(1)和不同(2)究竟在这里放松?

我唯一能想到的就是我误解了load意味着acquire。如果这是真的,并且默认值seq_cst意味着两者,那不就意味着一个完整的围栏 - 没有任何东西可以传递该指令,也不能传递?我一定误解了那部分。

[并且对称地用于存储释放]。

Cub*_*bbi 6

调用myatomic.load(std::memory_order_acquire);“宽松的原子”负载可能有点令人困惑,因为有一个std::memory_order_relaxed. 有些人将任何比seq_cst“放松”更弱的秩序描述为“放松”。

你注意到顺序一致加载是一个获取加载是正确的,但它有一个额外的要求:顺序一致加载也是所有 seq_cst 操作的总全局顺序的一部分。

当您处理多个原子变量时,它就会发挥作用:除非强加了顺序一致性,否则两个原子的单个修改顺序可能会以不同的相对顺序出现在不同的线程中。