何时使用gcc的-O2标志?

11
如果我使用"-O2"标志,性能会提高,但编译时间会变长。
我该如何决定是否使用?
也许O2对于某些特定类型的代码(例如数学计算)最有影响力,我应该仅针对项目中的这些部分使用它?
编辑:我想强调一下,将-O2设置为我项目的所有组件会将总编译时间从10分钟增加到30分钟。

2
这并不回答你的问题,但根据你的编辑,听起来你需要改变你构建项目的方式。在初始构建之后,它应该只编译修改过的源文件为.o文件,然后将.o文件链接在一起。 - cyberconte
预编译头文件也可以帮助提高构建性能。 - Zan Lynx
6个回答

26

我建议大部分时间使用 -O2,它的好处包括:

  • 通常可以减小生成代码的大小(与 -O3 不同)。
  • 更多的警告信息(一些警告需要优化期间才能进行分析)。
  • 通常可以明显地提高性能(这可能并不重要)。

如果发布级别的代码将启用优化,则最好在开发/测试周期中始终启用优化。

启用优化会使源代码级调试更加困难,有时在调试问题时禁用优化是有帮助的。


1
如果您需要减小代码大小,为什么不使用-Os而不是-O2呢? - Christoffer
3
如果代码大小是最需要优化的部分,那么使用 -Os 是有意义的。但通常情况下并非如此(除了在小型嵌入式系统中...)。 - Lance Richardson
我已经多次看到编译器在被告知优化尺寸时生成比被告知优化速度时更大的二进制文件。我总是只使用-O2,有时会使用-O3,但也承担相应的风险。 - old_timer

11

我从事生物信息学,因此我的建议可能有些偏见。不过,我-O3开关总是使用(针对发布和测试构建,而不通常用于调试)。的确,它有某些缺点,即增加了编译时间并且通常会增加可执行文件的大小。

然而,第一个因素可以通过良好的构建策略和其他技巧来部分缓解,以减少整体构建时间。此外,由于大多数编译实际上是I/O限制的,所以编译时间的增加通常不会非常明显。

第二个缺点,可执行文件的大小,通常根本不重要。


1
准确地说,正确构建您的项目并注意makefile中的依赖关系通常使编译时间不成问题。同样,这通常有助于可执行文件的大小,尽管我见过一些人做出非常愚蠢的事情导致程序变得非常庞大。 - Nikolai Fetissov
我喜欢这个答案,但我想补充一点,就是应该能够轻松地运行而无需优化,因为这样 GDB 的效果会更好。 - dicroce
1
根据我的经验,与链接时间相比,编译时间很容易修复。(现在是时候搜索“减少链接时间”的问题了!) - leander
对于编译时间和IO时间的争议,我的看法是-O3构建非常大的C++文件需要大量的CPU时间。我通过将它们连接在一起来构建非常大的C++文件,因为GCC 4.4及以前版本没有LTO。 - Zan Lynx
@Zan,你的情况比较特殊,因为你手动连接了C++文件。你可能知道这可以极大地减少IO开销,因为它可以防止重复读取包含文件。在最好的情况下,这可以有指数级的加速。 - Konrad Rudolph

6

永远不要。

使用 -O3 -Wall -Werror -std=[根据您的代码库应遵循的标准]


1
作为一项实验,我使用了-O3和-Os两种编译选项来构建LAME,但在分析后只有少数文件使用了-O3。大部分使用-Os的版本实际上比使用-O3的版本快了约10%。优化开关并不是一个神奇的性能调节器,但将其调到最高可能会使您的可执行文件变得更大,使调试更加困难,并引入与优化相关的错误。 - Left For Archive

5

除了编程时想测试刚写的东西以外,通常情况下不要这样做。


3

通常我们会设置构建环境,以便我们可以构建使用 -O0 的 调试版本 和使用 -O3 的 发布版本(构建环境保留所有配置的对象和库,以便用户可以轻松地在不同配置之间切换)。在开发过程中,为了更快的构建速度(和更准确的调试信息),大多数情况下都会构建和运行调试配置,并较少地构建和测试发布配置。


2
增加编译时间真的很明显吗?我通常将-O2作为默认选项,其他任何选项都会在代码中留下很多“摩擦”。还要注意的是,-O1、-O2优化级别往往是最好测试的,因为它们最有趣。在我的经验中,-O0往往更容易出现错误,并且你可以在-O2下进行很好的调试,只要你对编译器能够进行的代码重新排序、内联等方面有一些了解。
-Werror -Wall是必须的。

不知怎么的,将我的项目所有组件设置为 -O2 后,总编译时间从 10 分钟变为了 30 分钟。 - Igor
1
10分钟到30分钟。这足以让你避免它。收到。 - jakobengblom2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接