我看到很多人抱怨-O3
选项:
我查看了 GCC 的手册:
-O3 Optimize yet more. -O3 turns on all optimizations specified by -O2 and also turns on the -finline-functions and -frename-registers options.
而且我还确认了代码以确保两个选项是-O3
on 中仅有的两个优化:
if (optimize >= 3){
flag_inline_functions = 1;
flag_rename_registers = 1;
}
对于这两个优化:
-finline-functions
在某些情况下(主要用于 C++)很有用,因为它允许我们使用 -finline-limit 定义内联函数的大小(默认为 600)。当设置高内联限制时,编译器可能会报告一个错误,抱怨内存不足。-frename-registers
尝试通过使用寄存器分配后剩余的寄存器来避免调度代码中的错误依赖性。这种优化将最有利于具有大量寄存器的处理器。
对于内联函数,虽然可以减少函数调用的次数,但可能会导致二进制文件很大,因此-finline-functions
可能会引入严重的缓存惩罚,甚至比 -O2 还要慢。我认为缓存惩罚不仅取决于程序本身。
对于重命名寄存器,我认为它不会对像 x86 这样的 cisc 架构产生任何积极影响。
我的问题有 2.5 个部分:
我是否可以声称使用 -O3 选项是否可以更快地运行程序取决于底层平台/架构?[已回答]
编辑:
第一部分已被证实为真实。David Hammen 还声称,我们应该非常小心优化和浮点操作如何在具有扩展精度浮点寄存器(如 Intel 和 AMD)的机器上进行交互。
我什么时候可以自信地使用
-O3
选项?我想这两个优化,尤其是重命名寄存器可能会导致与 -O0/O2 不同的行为。我看到一些编译的程序-O3
在执行过程中崩溃了,它是确定性的吗?如果我运行一个可执行文件一次而没有任何崩溃,这是否意味着它可以安全使用-O3
?编辑:确定性与优化无关,它是一个多线程问题。
-O3
但是,对于多线程程序,当我们运行一次可执行文件而没有错误时,使用它是不安全的。David Hammen 表明-O3
浮点运算的优化可能违反严格的弱排序标准进行比较。当我们想使用选项时,还有其他需要注意的问题吗?-O3
如果第一个问题的答案是“是”,那么当我更改目标平台或在具有不同机器的分布式系统中时,我可能需要在 和 之间进行
-O3
更改-O2
。有没有什么通用的方法来决定我是否可以通过 获得性能改进-O3
?比如更多的寄存器,短的内联函数等【已回答】编辑:Louen 回答了第 3 部分,因为“平台的多样性使得对这个问题的一般推理变得不可能” 当通过 评估性能增益时
-O3
,我们必须对两者进行尝试并对我们的代码进行基准测试以查看哪个更快。