优化级别 -O3 在 g 中是否危险?

新手上路,请多包涵

我从各种来源(尽管主要来自我的一位同事)听说,在 g++ 中以 -O3 的优化级别进行编译在某种程度上是“危险的”,除非证明是必要的,否则一般应避免。

这是真的吗?如果是,为什么?我应该坚持 -O2 吗?

原文由 Matt Dunn 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.6k
2 个回答

在 gcc(2.8 等)的早期和 egcs 时代,redhat 2.96 -O3 有时会出现很多问题。但这是十多年前的事了,-O3 与其他级别的优化(在 buggyness 中)没有太大区别。

然而,由于更严格地依赖于语言的规则,尤其是极端情况,它确实倾向于揭示人们依赖未定义行为的情况。

作为个人说明,我多年来一直使用 -O3 在金融领域运行生产软件,并且还没有遇到如果我使用 -O2 就不会出现的错误。

根据大众的需求,这里增加一个:

-O3 尤其是附加标志,如 -funroll-loops(-O3 未启用)有时会导致生成更多机器代码。在某些情况下(例如在具有异常小的 L1 指令缓存的 CPU 上),这可能会导致速度变慢,因为例如某些内部循环的所有代码现在不再适合 L1I。通常 gcc 会努力不生成这么多代码,但由于它通常会优化通用案例,因此可能会发生这种情况。特别容易出现这种情况的选项(如循环展开)通常不包含在 -O3 中,并在手册页中相应地标记。因此,使用-O3 生成快速代码通常是一个好主意,并且仅在适当时(例如,当分析器指示L1I 未命中时)回退到-O2 或-Os(尝试优化代码大小)。

如果您想将优化发挥到极致,您可以通过 –param 在 gcc 中调整与某些优化相关的成本。另外请注意,gcc 现在能够将属性放在仅控制这些函数的优化设置的函数中,因此当您发现 -O3 在一个函数中存在问题时(或只想为该函数尝试特殊标志),您不需要使用 O2 编译整个文件甚至整个项目。

otoh似乎在使用-Ofast时必须小心,它指出:

-Ofast 启用所有 -O3 优化。它还支持并非对所有符合标准的程序都有效的优化。

这使我得出结论, -O3 旨在完全符合标准。

原文由 PlasmaHH 发布,翻译遵循 CC BY-SA 3.0 许可协议

是的,O3 更麻烦。我是一名编译器开发人员,在构建我自己的软件时,我发现了由 O3 生成有缺陷的 SIMD 汇编指令引起的清晰而明显的 gcc 错误。据我所见,大多数生产软件都附带 O2,这意味着 O3 在测试和错误修复方面受到的关注较少。

可以这样想:O3 在 O2 之上添加了更多转换,这在 O1 之上添加了更多转换。从统计学上讲,更多的转换意味着更多的错误。对于任何编译器都是如此。

原文由 David Yeager 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题