代码优化发生时?

Ras*_*yak 5 c optimization runtime compile-time

昨天,我接受了采访.在那里,他们问我代码优化何时发生?说,

int abc;//Global variable
abc = 3;
if(abc == 3)
{
  printf("abc will be always 3");
}
else
{
  printf("This will never executed");
}
Run Code Online (Sandbox Code Playgroud)

现在的问题是优化何时发生?A ...在运行时B ...在编译时.我在编译时回答...我想,编译器在编译时检查volatile关键字.如果变量未声明为volatile,则优化代码.但是,当编译器知道这一点时,这个变量永远不会超过3吗?如果是在运行时,那么当编译器知道变量永远不会超过3时?因为如果在执行这部分代码之后要改变变量.请清除我的怀疑

NPE*_*NPE 8

C代码通常使用静态(aka提前编译)编译来编译.一旦离开编译器,代码就会一成不变; 它不能在运行时更改.

这与使用即时编译的语言形成对比,例如Java.在那里,优化可以在程序运行时随时发生.


ssu*_*ube 4

大多数代码优化不能在运行时发生,至少不是你的意思。代码在执行过程中无法更改以反映一组新的或不同的变量,这只会造成绝对的混乱。

在运行时可以做的是通过代码选择最佳路径,但这主要必须手动完成,以便创建单独的路径、早期退出、分支等以允许优化。

像这样的代码,正如所写的,允许编译时优化,因为编译器可以检查任何可能的替代值abc,如果没有找到,则优化调用。然而,搜索的范围极大地影响了这种情况是否会发生,而编译器设置也会影响这一点。

如果编译器只是天真地优化单个目标文件,并且您的第二行位于打印部分的另一个文件中,那么它可能无法保证abc不会更改,因此根本无法优化它。无论变量的使用如何,这都取决于编译器设置的激进程度以及是否允许它们丢弃死分支,或者是否会考虑这样做。优化大小可能比速度更有可能删除分支,但中/高设置可能会以任何方式实现(如果可能)。

大多数现代编译器都有一个整体程序优化选项,它将大部分优化延迟到链接器阶段。这允许它搜索整个程序,有可能发现abc从未在其他地方更改或使用过的程序,并从条件中删除变量和失败的分支。整个程序优化比针对每个对象单独优化要有效得多,因为它可以允许更准确的搜索。

在编译器无法修剪死代码的情况下,您可以提示它(最近的构造可以constexpr帮助解决这个问题)或自己添加优化。它可以很简单,只需将最有可能的路径放在前面,并在 else 之前包含一个 return,从而避免 CPU 进行跳转。这种微观优化不太可能是必要的,尤其是在像这样的简单示例中,if本身就已经进行了大量优化。