memory_order_relaxed是否尊重同一线程内的数据依赖关系



给定:

std::atomic<uint64_t> x;
uint64_t f()
{
x.store(20, std::memory_order::memory_order_relaxed);
x.store(10, std::memory_order::memory_order_relaxed);
return x.load(std::memory_order::memory_order_relaxed);
}

假设只有一个线程在写入xf是否可能返回除10以外的值?对于非原子变量来说,这显然不是真的,但我不知道related是否如此宽松,以至于它会忽略同一线程中的数据依赖关系?

加载的结果总是10(假设只有一个线程)。即使是一个松弛的原子变量也是"零";更强的";比非原子变量:

  1. 与非原子变量一样,所有线程必须在对该变量进行所有修改的单一顺序上达成一致
  2. 与非原子变量一样;在";关系,以及
  3. 该实现将保证潜在的并发访问将以某种方式按照所有线程都会同意的顺序进行排序(从而满足需求1)。另一方面,在非原子变量的情况下,潜在的并发访问会导致未定义的行为

松弛的原子变量不能用于同步不同的线程,除非带有显式围栏。与适用于原子变量的其他内存顺序相比,这就是它放松的意义。

关于语言律师,请参阅C++20〔Introdur.races〕/10:

如果

  • AB之前排序,或[…]

和[interro.races]/15:

如果修改原子对象M的操作A发生在修改M操作B之前,则A应早于B,修改顺序为M&em>。[注意:此要求称为写-写连贯性。——尾注]

和[intro.races]/18:

如果原子对象M上的副作用X发生在M的值计算B之前,则评估B应从X或从X后的副作用Y中取值,修改顺序为M。[注意:这一要求被称为读写一致性。--尾注]

因此,在您的程序中,20的存储发生在10的存储之前(因为它是在它之前排序的),而10的存储则发生在加载之前。写-写一致性要求保证10的存储在x的修改顺序中晚于20的存储。当负载发生时,需要从10的存储中获取其值,因为10的存储发生在它之前,并且按照x的修改顺序,在10的存储之后没有其他修改。

最新更新