[英]Does as-if rule prevent compiler reordering of accesses to global/member variables?
我正在研究编译器优化(特别是此处的指令重新排序)对多线程程序可能产生的影响。
假设我们有一个读者线程和一个写作者线程。
// Global shared data between threads
bool data;
bool flag = false;
// writer.cpp
void writer()
{
data = true; // (1)
flag = true; // (2)
}
// reader.cpp
void reader()
{
if (flag)
{
count << data;
}
}
可以使用符合C ++ 11的编译器对指令(1)
和(2)
重新排序吗?
根据C ++的“假设”规则,转换不应更改程序的可观察行为。 显然,在编译writer时,编译器通常无法确定重新排序(1)
和(2)
是否会更改程序的可观察行为,因为data
和flag
都是全局变量,可能会影响另一个线程的可观察行为。
但它在此声明可以发生这种重新排序,请参阅编译时的内存排序 。
那么我们是否需要(1)
和(2)
之间的编译器障碍? (我很清楚可能的CPU重新排序。这个问题仅适用于编译器重新排序)
绝对可以。 编译器没有义务考虑其他线程或硬件的副作用。
仅当您使用volatile
或同步(并且二者不可互换)时,编译器才被迫考虑这一点。
标准内存模型称为SC-DRF,或顺序一致数据竞争免费。 数据竞争正是您刚刚描述的情景 - 其中一个线程正在观察非同步变量而另一个线程正在变异。 这是未定义的行为。 实际上,标准明确地赋予编译器自由,假设没有其他线程或硬件正在读取非易失性非同步变量。 编译器在此基础上进行优化是绝对合法的。
顺便说一下,该链接有点废话。 他的“修复”并没有解决任何问题。 多线程代码的唯一正确解决方法是使用同步。
您已经在一周半前的comp.lang.c ++。mode中提出了这个问题,并且已获得有关C ++ 11对单个线程内排序和“之前发生”的要求之间的关系的完整说明。线程之间的同步关系,请参见: https : //groups.google.com/forum/#!topic / comp.lang.c ++。moderated / 43_laZwVXYg
您不了解该回复的哪一部分,我们可以再试一次?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.