C++ 11内存模型是否允许从循环中提升放松的原子载荷?

Muh*_*rma 11 c++ atomic atomicity c++11

请考虑以下代码:

#include <atomic>

extern std::atomic<int> i;

void f(void)
{
  while (!i.load(std::memory_order_relaxed))
      ;
}
Run Code Online (Sandbox Code Playgroud)

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

  if (!i.load(std::memory_order_relaxed)) {
    while (1)
      ;
  }
Run Code Online (Sandbox Code Playgroud)

我在这里看过一些讨论,但没有结论.

编辑:这篇文章的先前版本称为循环内部的外部函数.

编辑2:动机:"Effective Java"一书说HotSpot VM执行以下转换:

while (!done)
    i++;
Run Code Online (Sandbox Code Playgroud)

if (!done)
    while (true)
        i++;
Run Code Online (Sandbox Code Playgroud)

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

T.C*_*.C. 2

忘记放松吧,不能保证原子存储对不同线程中的原子加载可见你得到的最好的结果是[atomics.order]/12中的规范性鼓励(以及[intro.progress]/18中的类似措辞)):

\n\n
\n

实现应该使原子存储在合理的时间内对原子加载可见。

\n
\n\n

...这不是一个要求。

\n\n

(C11 在 \xc2\xa77.11.3/16 中具有相同的措辞)

\n\n

由于提升负载导致的行为与非提升负载无法区分,其中存储永远不会变得可见,并且由于后者是一致的,因此 as-if 规则允许实现提升负载,而不管使用的内存顺序如何。

\n