【发布时间】:2008-09-18 05:10:12
【问题描述】:
GCC 中不同的优化级别有什么区别?假设我不在乎有任何调试钩子,我为什么不只使用我可用的最高级别的优化呢?更高级别的优化是否必然(即可证明)生成更快的程序?
【问题讨论】:
GCC 中不同的优化级别有什么区别?假设我不在乎有任何调试钩子,我为什么不只使用我可用的最高级别的优化呢?更高级别的优化是否必然(即可证明)生成更快的程序?
【问题讨论】:
是的,更高的级别有时可能意味着程序性能更好。但是,根据您的代码,它可能会导致问题。例如,分支预测(在 -O1 及更高版本中启用)可以通过导致竞争条件来破坏编写不佳的多线程程序。优化实际上会决定一些比你写的更好的东西,这在某些情况下可能不起作用。
有时,更高的优化 (-O3) 不会增加任何合理的好处,但会增加很多额外的大小。您自己的测试可以确定这种大小权衡是否能为您的系统带来合理的性能提升。
最后一点,GNU 项目在-O2 by default 编译所有程序,-O2 在其他地方相当常见。
【讨论】:
通常高于-O2 的优化级别(对于 gcc 只有-O3,但其他编译器有更高的优化级别)包括可以增加代码大小的优化。这包括循环展开、大量内联、对齐填充(无论大小)等。其他编译器提供高于-O3 级别的向量化和过程间优化,以及某些可以大大提高速度的优化。正确性的成本(例如,使用更快、不太准确的数学例程)。在使用这些东西之前检查文档。
至于性能,这是一个权衡。一般来说,编译器设计者会尝试调整这些东西,以免它们降低代码的性能,所以-O3 通常会有所帮助(至少根据我的经验),但你的里程可能会有所不同。真正激进的大小更改优化并不总是会提高性能(例如,真正激进的内联会导致缓存污染)。
【讨论】:
我发现了一个web page,其中包含有关不同优化级别的一些信息。记得在某处听到的一件事是优化实际上可能会破坏您的程序,这可能是一个问题。但我不确定这个问题有多大。也许今天的编译器足够聪明,可以处理这些问题。
【讨论】:
-O 级别开启的优化破坏了您的程序,那么几乎可以肯定是您的程序出了问题(调用未定义的行为),而不是优化。
旁注:
很难准确预测 gcc 命令行上针对不同版本和平台的全局 -O 指令打开了哪些标志,并且 GCC 站点上的所有文档可能很快就会过时或不涵盖编译器内部结构足够详细。
当您使用其中一个 -O 标志和其他 -f 标志和/或它们的组合时,这是一种简单的方法来准确检查您的特定设置会发生什么:
touch dummy.c
-O、-f和/或-m标志你通常会使用,但在命令行中添加-Q -v:rm -f dummy.o删除生成的目标文件并重新运行。另外,请始终牢记,从纯粹的角度来看,大多数非平凡优化都会生成“损坏”代码(其中损坏定义为在极端情况下偏离最佳路径),因此选择是否启用某些优化机制有时归结为选择编译器输出的正确性级别。在任何编译器的优化器中总是存在(并且目前存在)错误 - 只需检查 GCC 邮件列表和 Bugzilla 以获取一些示例。编译器优化只能在实际执行测量后使用,因为
【讨论】: