全局排序和每原子变量排序有何不同

How does global ordering and per atomic variable ordering differ?

本文关键字:排序 变量 何不同 全局      更新时间:2023-10-16

我正在努力理解memory_order_seq_cst和memory_order_aq_rel之间的区别。SO上的一些帖子已经涵盖了这个问题,然而,我不明白他们的答案。

这个帖子说

memory_order_aq_rel提供相对于原子变量的读和写顺序,而memory_orden_seq_cst提供全局读和写排序。

它还包括一个示例

bool x= false;
bool y= false;
bool z= 0;
a() { x= true; }
b() { y= true; }
c() { while (!x); if (y) z++; }
d() { while (!y); if (x) z++; }
// kick off a, b, c, d, join all threads
assert(z!=0);

这个片段是cppreference.com上一个例子的骨架版本。我在Ideone和CoLiRu上编译了这个例子。在Ideone上,在memory_order_aq_rel和memory_orden_seq_cst下,z可以是1或2。在CoLiRu上,我只能得到2。它从来都不是0。

我的问题是:

  1. while(!x)和while(!y)是否保证if(y)或if(x)返回true,即使我们使用每原子变量排序
  2. 这个例子如何解释memory_order_aq_rel和memory_orden_seq_cst之间的区别
  3. 有人能提供一个使用内存栅栏的例子来说明每原子变量排序和全局排序之间的区别吗

c++11标准将seq_cst定义为

所有memory_order_seq_cst操作都应有一个总订单S,与所有受影响位置的"发生之前"订单和修改订单一致。。。

请注意,这些操作可能在不同的内存位置上。在acq_rel排序的情况下,该顺序仅在相关的内存位置上保持。

在您提供的示例中,我假设当您说"under memory_order_aq_rel"时,您的意思是说程序中的所有存储和加载都有memory_order_aq_rel(与memory_orden_seq_cst相同)。memory_order_seq_cst的排序要求将对xy的所有加载/存储操作强制执行总顺序,这意味着x=true;发生在y=true之前,或者y=true发生在x=true之前。因此CCD_ 7的可能值为1或2。而在memory_order_acq_rel的情况下,如果线程c中加载的xy的值分别为1和0,并不意味着线程d不能将y读取为1,将x读取为0。在这种情况下,CCD_ 12的值将为0。因此,这允许z的值为0、1或2。