【问题标题】:What is the difference between gcc optimization levels?gcc优化级别有什么区别?
【发布时间】:2008-09-18 05:10:12
【问题描述】:

GCC 中不同的优化级别有什么区别?假设我不在乎有任何调试钩子,我为什么不只使用我可用的最高级别的优化呢?更高级别的优化是否必然(即可证明)生成更快的程序?

【问题讨论】:

    标签: linux gcc


    【解决方案1】:

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

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

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

    【讨论】:

    • 至于优化级别之间的实际差异,请参阅文档as here for GCC 5.2.0。值得注意的是,有时优化大小 -Os 可以带来更高的性能,我相信这是由于处理器缓存中的代码。
    【解决方案2】:

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

    至于性能,这是一个权衡。一般来说,编译器设计者会尝试调整这些东西,以免它们降低代码的性能,所以-O3 通常会有所帮助(至少根据我的经验),但你的里程可能会有所不同。真正激进的大小更改优化并不总是会提高性能(例如,真正激进的内联会导致缓存污染)。

    【讨论】:

      【解决方案3】:

      我发现了一个web page,其中包含有关不同优化级别的一些信息。记得在某处听到的一件事是优化实际上可能会破坏您的程序,这可能是一个问题。但我不确定这个问题有多大。也许今天的编译器足够聪明,可以处理这些问题。

      【讨论】:

      • 一个技巧是编写一个实际上在整数溢出时中断的无限循环,并尝试各种级别的优化。在我的机器上,32 位整数溢出在 -O0 处需要 10 秒,在 -O1 处需要 2 秒,并在 -O2 处优化为无限循环。
      • 如果任何-O 级别开启的优化破坏了您的程序,那么几乎可以肯定是您的程序出了问题(调用未定义的行为),而不是优化。
      • 例如,在 C++ 中,有符号整数溢出是未定义的行为。这意味着编译器可以对您的代码做任何事情。无限循环、在 0.0001 秒内中断、弹出 CD 驱动器、使用网络摄像头向前任发送令人尴尬的照片或投票给 Buchanan 都是免费的。优化很少会真正破坏您的代码;它可能会让你知道你的代码一直被破坏。
      【解决方案4】:

      旁注:

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

      当您使用其中一个 -O 标志和其他 -f 标志和/或它们的组合时,这是一种简单的方法来准确检查您的特定设置会发生什么:

      1. 在某处创建一个空源文件:
        touch dummy.c
      2. 尽管编译器通过了,但运行它就像你通常那样,所有-O-f和/或-m标志你通常会使用,但在命令行中添加-Q -v
        @ 987654329@
      3. 检查生成的输出,可能会将其保存以供不同的运行使用。
      4. 根据自己的喜好更改命令行,通过rm -f dummy.o删除生成的目标文件并重新运行。

      另外,请始终牢记,从纯粹的角度来看,大多数非平凡优化都会生成“损坏”代码(其中损坏定义为在极端情况下偏离最佳路径),因此选择是否启用某些优化机制有时归结为选择编译器输出的正确性级别。在任何编译器的优化器中总是存在(并且目前存在)错误 - 只需检查 GCC 邮件列表和 Bugzilla 以获取一些示例。编译器优化只能在实际执行测量后使用,因为

      • 使用更好的算法所获得的收益将使编译器优化所获得的收益相形见绌,
      • 没有必要优化每次都会运行一次的代码,
      • 如果优化器引入了错误,那么您的代码运行速度有多快并不重要。

      【讨论】:

        猜你喜欢
        • 2020-06-08
        • 2010-12-19
        • 1970-01-01
        • 2018-03-24
        • 2013-09-19
        • 2016-01-01
        • 1970-01-01
        • 2010-10-14
        • 2011-08-16
        相关资源
        最近更新 更多