2010-09-27 46 views
5

即使我在Visual C++中打开完全优化,编译器是否有任何理由不能优化以下两条语句:任何副作用在内存中访问一个int变量?为什么编译器不能优化这两条语句?

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    volatile int pleaseOptimizeMeOut = 100; 

    (pleaseOptimizeMeOut); 

    return 0; 
} 

回答

16

由于您声明变量为volatile,所以无法优化它们。加载和存储到volatile合格对象是C抽象机器的“外部可见”效果的一部分。 (顺便说一下,在访问内存中的变量时,有大量的大量;它可以更新包括TLB在内的硬件内存缓存,并且可能还会导致页面错误,并且您的进程正在执行的内存可能会被另一个进程窥探,如调试器)。

+5

这种效应是volatile类型的“点”。 – SingleNegationElimination 2010-09-27 03:44:59

5

在某些计算机上,设备I/O被建模为内存读取/写入。当volatile被恰当地使用时,这就是这种情况...它告诉编译器明确不要假设变量操作不重要或可以被优化......

8

volatile明确地告诉编译器不要优化那个变量。

4

其他答案强调了这里volatile的重要性,我没有什么补充。不过,我想说的是,这样的结构是多么的重要,因为有用。根据我的硬件设计经验,HW中的CPU和逻辑块之间的接口多次基于内存写入和读取。这意味着当CPU从HW中读取一些寄存器时,会发生一些事情(例如,中断清除,队列提前和其他许多选项)。

现在,一旦你执行访问pleaseOptimizeMeOut,因为它是volatile编译器只是假定你可能已经做了只是副作用,所以这将是绝对错误的优化。假设变量映射到一个硬件队列,并且你只是想提前队列而不真正从中获取一个值。

这就是说,在读取时将变量映射到寄存器有副作用是恕我直言不是一个好习惯,并且最好用函数调用来封装它,这正是您的问题所展示的原因 - 在某些情况下会造成混淆。

将变量映射到无副作用的寄存器非常有用且广泛使用,但是。