即使我在 Visual C++ 中打开了完全优化,编译器是否有任何理由无法在 main 中优化以下 2 条语句?访问内存中的 int 变量有什么副作用吗?
int _tmain(int argc, _TCHAR* argv[])
{
volatile int pleaseOptimizeMeOut = 100;
(pleaseOptimizeMeOut);
return 0;
}
即使我在 Visual C++ 中打开了完全优化,编译器是否有任何理由无法在 main 中优化以下 2 条语句?访问内存中的 int 变量有什么副作用吗?
int _tmain(int argc, _TCHAR* argv[])
{
volatile int pleaseOptimizeMeOut = 100;
(pleaseOptimizeMeOut);
return 0;
}
它无法优化它们,因为您已将变量声明为volatile
. volatile
对合格对象的加载和存储是 C 抽象机的“外部可见”效果的一部分。
(顺便说一句,访问内存中的变量时有很多副作用;它可以更新包括 TLB 在内的硬件内存缓存,还可能导致页面错误。并且您的进程正在执行的内存可能被另一个进程窥探进程,如调试器)。
volatile
明确告诉编译器不要针对该变量进行优化。
在某些计算机上,设备 I/O 被建模为内存读/写。这就是正确使用 volatile 时的那种情况......它明确告诉编译器不要假设变量操作不重要或可以优化......
其他答案强调了volatile
这里的重要性,对此我没有什么要补充的。但是,我想说的是,存在这样的结构是多么重要,因为它很有用。根据我的硬件设计经验,很多时候 CPU 和硬件中的逻辑块之间的接口是基于内存写入和读取的。这意味着当 CPU 从硬件读取某个寄存器时,会发生一些事情(即中断清除、队列推进和许多其他选项)。
现在,一旦您执行对 的访问pleaseOptimizeMeOut
,因为它是volatile
编译器只是假设您可能只是为了副作用才这样做,所以优化它是绝对错误的。假设变量映射到一个硬件队列,而您只是想推进队列而不实际从中获取值。
也就是说,当读取有副作用时将变量映射到寄存器恕我直言不是一个好习惯,最好用函数调用封装它,这正是您的问题所表明的原因 - 在某些情况下会令人困惑。
然而,将变量映射到没有副作用的寄存器非常有用并且被广泛使用。