gcc优化级别有什么区别?

时间:2008-09-18 05:10:13

标签: linux gcc

GCC中不同优化级别之间的区别是什么?假设我不关心任何调试挂钩,为什么我不能使用可用的最高级别的优化?更高水平的优化是否必然(即可证明)产生更快的程序?

4 个答案:

答案 0 :(得分:14)

是的,更高的水平有时可能意味着更好的表现。但是,根据您的代码,它可能会导致问题。例如,分支预测(在-O1和up中启用)可以通过引起竞争条件来破坏写得不好的多线程程序。优化实际上会决定比你写的更好的东西,在某些情况下可能不起作用。

有时,较高的优化(-O3)不会增加任何合理的好处,但需要额外的大小。您自己的测试可以确定此大小权衡是否为您的系统带来合理的性能提升。

作为最后一点,GNU项目在-O2 by default编译所有程序,-O2在其他地方相当普遍。

答案 1 :(得分:13)

通常优化级别高于-O2(gcc只有-O3但其他编译器的优化级别更高)包括可以增加代码大小的优化。这包括循环展开,大量内联,无论大小的对齐填充等等。其他编译器提供高于-O3的级别的矢量化和过程间优化,以及可以提高速度的某些优化以正确为代价(例如,使用更快,更准确的数学例程)。在使用这些内容之前检查文档。

至于表现,这是一个权衡。通常,编译器设计者会尝试调整这些内容,以免降低代码的性能,因此-O3通常会有所帮助(至少在我的经验中),但您的里程可能会有所不同。并非总是如此,真正积极的大小改变优化将提高性能(例如,真正积极的内联可以让您缓存污染)。

答案 2 :(得分:3)

我发现web page包含有关不同优化级别的一些信息。记住某个地方的一件事是,优化可能实际上破坏了你的程序,这可能是一个问题。但我不确定一个问题有多长。也许今天的编译器足够智能来处理这些问题。

答案 3 :(得分:1)

旁注:

很难准确地预测gcc命令行上针对不同版本和平台的全局-O指令打开了哪些标志,并且GCC站点上的所有文档可能很快就会过时或者不会过时t足够详细地介绍编译器内部。

使用其中一个-O标记和其他-f标记和/或其组合时,可以通过以下方法快速检查特定设置上发生的情况:

  1. 在某处创建一个空的源文件:
    touch dummy.c
  2. 通过编译器正常运行,然后使用通常使用的所有-O-f和/或-m标记运行它,但添加-Q -v到命令行:
    gcc -c -Q -v dummy.c
  3. 检查生成的输出,可能将其保存为不同的运行。
  4. 根据自己的喜好更改命令行,通过rm -f dummy.o删除生成的目标文件并重新运行。
  5. 此外,请始终牢记,从纯粹主义的角度来看,大多数非平凡的优化都会产生“破坏”的代码(其中破坏被定义为偏离极端情况下的最佳路径),因此选择是否要启用某组优化机制有时可归结为选择编译器输出的正确性级别。在任何编译器的优化器中总是存在(当前存在)错误 - 只需检查GCC邮件列表和Bugzilla中的一些示例。编译器优化只应在实际执行测量后使用,因为

    • 使用更好的算法获得的收益会使编译器优化的任何收益相形见绌,
    • 优化代码没有意义
    • 如果优化器引入了错误,那么代码的运行速度并不重要。