C ++ 11内存模型是否允许将松弛的原子负载提升到循环之外? [英] Does the C++11 memory model allow hoisting relaxed atomic loads out of loops?
问题描述
考虑以下代码:
#include <atomic>
extern std::atomic<int> i;
void f(void)
{
while (!i.load(std::memory_order_relaxed))
;
}
我正在寻找C ++ 11标准的引用,该标准指出不允许编译器将循环转换为
I'm looking for a citation from the C++11 standard that says that the compiler is not allowed to transform the loop into
if (!i.load(std::memory_order_relaxed)) {
while (1)
;
}
我在此处看到了一些讨论,但没有定论.
I've seen some discussion here but nothing conclusive.
编辑:该帖子的先前版本在循环内称为extern函数.
Edit: A previous version of this post called an extern function inside the loop.
编辑2 :出于动机:《有效Java》一书中指出,HotSpot VM执行以下转换:
Edit 2: For motivation: The book "Effective Java" says that the HotSpot VM performs the following transformation:
while (!done)
i++;
到
if (!done)
while (true)
i++;
即使另一个线程同时更改 done 变量是完美定义的行为.
even though it's perfectly defined behavior for another thread to change the done variable concurrently.
推荐答案
忘了放松,不能保证原子存储 ever 在其他线程中对于原子加载是可见的.最好的方法是 [atomics.order]/12 (和 [intro.progress]/18 中的类似措词):
Forget about relaxed, there's no guarantee that an atomic store ever become visible to an atomic load in a different thread. The best you get is the normative encouragement in [atomics.order]/12 (and analogous wording in [intro.progress]/18):
实施应使原子存储对原子负载可见 在合理的时间内.
Implementations should make atomic stores visible to atomic loads within a reasonable amount of time.
...这不是必需的.
...which is not a requirement.
(C11在§7.11.3/16中具有相同的用语)
(C11 has identical wording in §7.11.3/16)
由于提升负载导致行为与无法提升存储(从不可见)的非提升负载无法区分,并且由于后者是符合标准的,因此按规则可以通过一种实现方式来提升负载,而与内存顺序无关使用.
Since hoisting the load leads to behavior indistinguishable from a non-hoisted load where the store never becomes visible, and since the latter is conforming, an implementation is allowed by the as-if rule to hoist the load regardless of the memory order used.
这篇关于C ++ 11内存模型是否允许将松弛的原子负载提升到循环之外?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!