系统相关
首页 > 系统相关> > C 11内存模型是否允许将松弛的原子负载提升到循环之外?

C 11内存模型是否允许将松弛的原子负载提升到循环之外?

作者:互联网

考虑以下代码:

#include <atomic>

extern std::atomic<int> i;

void f(void)
{
  while (!i.load(std::memory_order_relaxed))
      ;
}

我正在寻找C 11标准的引文,该标准说不允许编译器将循环转换为

  if (!i.load(std::memory_order_relaxed)) {
    while (1)
      ;
  }

我看过一些讨论here,但没有定论.

编辑:此帖子的先前版本在循环内称为extern函数.

编辑2:出于动机:《有效Java》一书中说,HotSpot VM执行以下转换:

while (!done)
    i++;

if (!done)
    while (true)
        i++;

即使另一个线程同时更改完成的变量是完美定义的行为.

解决方法:

忘了放松,并不能保证原子存储在其他线程中对原子负载都是可见的.您得到的最好的是[atomics.order]/12中的规范性鼓励(以及[intro.progress]/18中的类似措辞):

Implementations should make atomic stores visible to atomic loads
within a reasonable amount of time.

…这不是必需的.

(C11在§7.11.3/ 16中具有相同的措词)

由于提升负载导致行为与无法提升存储区的非提升负载没有区别,并且由于后者符合要求,因此按原样的规则允许实施提升负载,而与所使用的内存顺序无关.

标签:c,c11,atomicity,atomic
来源: https://codeday.me/bug/20191010/1886999.html