使用-g gcc标志编译的程序是否比不使用-g更慢?

56
我正在使用 -O3 以提高程序的性能,同时使用 -g 添加调试符号(以防崩溃时使用核心转储)。有一件事情让我非常困扰,-g 选项会导致性能下降吗?当我对比带有和不带有 -g 的编译输出时,我发现不带 -g 的输出要比带 -g 的输出小80%。如果额外的空间用于调试符号,我不关心它(我猜)因为这部分在运行时是不会被使用的。但是,如果在没有 -g 的编译输出中,每个指令需要做4个以上的指令,在带有 -g 的编译输出中,则肯定更喜欢停止使用 -g 选项,即使代价是不能处理核心转储。

如何知道程序内调试符号部分的大小,总之,是否使用 -g 进行编译会导致程序运行比不使用 -g 编译的同样代码运行更慢?

1
你做过基准测试吗? - Shiplu Mokaddim
5
要对这个程序进行基准测试确实不容易,如果容易的话我就不会问这个问题了,我会自己测量惩罚。 - e271p314
3
我已经进行了测量。它们似乎以相同的速度运行。 -g 只是添加调试符号。显然,这取决于你的程序。 - Shiplu Mokaddim
5
MSVC使用单独的PDB文件来存储调试符号,您甚至可以在发行模式下进行调试,因此有时您甚至会遇到被优化掉其值未定义的变量。我不知道gcc是否有类似的选项。 - phuclv
1个回答

69
引用自gcc文档

GCC允许您在使用-O选项时使用-g选项。优化代码所采取的捷径可能会产生令人惊讶的结果:有些声明的变量根本不存在;控制流可能会在您意料之外短暂移动;某些语句可能不会被执行,因为它们计算出常数结果或它们的值已经准备就绪;一些语句可能会在不同的位置执行,因为它们已经移出了循环。

这意味着:

我将为您插入调试符号,但如果优化过程删除它们,我不会尝试保留它们,您必须处理这个问题。

调试符号不是写入代码中的,而是写入另一个称为“调试节”(debug section)的部分中,在运行时甚至都没有加载(仅由调试器加载)。这意味着:没有代码更改。您不应该注意到代码执行速度上的任何性能差异,但如果加载器需要处理较大的二进制文件或以某种方式考虑增加的二进制文件大小,则可能会遇到一些缓慢。您可能需要自己对应用程序进行基准测试以确保100%确定您的特定情况。
请注意,从gcc 4.8开始还有另一个选项

-Og

优化调试体验。-Og启用不会干扰调试的优化。它应该是标准编辑-编译-调试周期的优化级别,提供合理的优化水平,同时保持快速编译和良好的调试体验。

此标志影响性能,因为它将禁用任何可能干扰调试信息的优化过程。

最后,有时候可能会发生一些优化措施更适合于特定架构而不是其他架构,如果您没有为特定处理器指定(请参见march/mtune选项以了解您的架构),在O3中gcc将尽其所能为通用架构做出最佳贡献。这意味着在一些人为情况下,你甚至可能会发现O3比O2更慢。 “尽力而为”并不总是意味着“最好的选择”。


1
顺便说一句,你甚至可以指定如何实现,即 marchmtune - edmz
7
请注意,即使您由于使用了“-g”而注意到性能差异,也可以使用“objcopy --strip-debug”和“objcopy --only-keep-debug”将调试信息移到单独的文件中。 - user743382

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