繁体   English   中英

as-if规则是否阻止编译器重新排序对全局/成员变量的访问?

[英]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)是否会更改程序的可观察行为,因为dataflag都是全局变量,可能会影响另一个线程的可观察行为。

但它在此声明可以发生这种重新排序,请参阅编译时的内存排序

那么我们是否需要(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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM