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