使用-g本身进行编译是否会降低性能?

Does compiling with -g, in itself, degrade performance?

本文关键字:性能 是否 编译 使用      更新时间:2023-10-16

(这是一个关于gcc和clang的问题,但可能适用于其他编译器)

如果我编译我的C或c++代码,并使用-g开关生成调试信息,这本身是否会以任何方式降低编译程序的性能…

  1. 最小优化(-O0)?
  2. 最大优化(-O3)?

注意:我不是指必须解析/加载可执行文件的性能损失,由于额外的内容,这是较大的;我指的是运行的代码

我不认为有任何性能差异。实际上,生成的代码是相同的,根据这里的文档,-g可以与-O一起使用。此外,调试符号不会写入代码,而是写入另一个称为"调试段"的部分,该部分甚至不会在运行时加载(仅由调试器加载)

-g不会改变运行的优化或生成的代码。

然而,可能需要注意的是,同一文档声明:

优化后的代码所采用的快捷方式有时会令人惊讶:你声明的一些变量可能根本不存在;控制流程可能短暂地移动到你没有预料到的地方;有些陈述可能不是执行是因为它们计算常数结果或它们的值是已经在手边的;有些语句可能在不同的地方执行因为它们被移出了循环。然而,这是可能的调试优化的输出。这使得使用为可能存在错误的程序提供优化器。

所以最后的调试永远不会损害你的优化,但相反是假的,使用-O3可能会降低你的调试信息(通过删除无用的变量,例如)。

请注意,在这种情况下使用-Og(如这里所述)可能会更好,因为它将:

优化调试体验。-Og允许不需要的优化干扰调试。它应该是的优化级别选择标准的编辑-编译-调试周期,提供一个合理的优化水平,同时保持快速编译以及良好的调试体验。

然而,这将影响性能,因为一些会干扰调试的优化传递将不会完成。


编辑:

链接和引号回答了gcc的问题。它可能不适用于其他编译器,如clang。然而,我也发现了一些clang的文档。例如:

基本上,调试信息允许你编译一个程序" - 0 -g "并获得完整的调试信息,允许您任意调试在程序从调试器执行时修改程序。编译程序使用"-O3 -g"为您提供完整的调试信息可用和准确的读取(例如,你得到准确的堆栈踪迹,尽管尾部呼叫消除和内联),但你可能会输修改程序和调用函数的能力在程序外优化,或者完全内联。

-g标志向二进制文件中添加调试信息。它存在于.text CPU运行位的可执行文件的单独部分(.stab.stabstr)中。当在调试器外运行时,操作系统加载程序不会加载调试部分。也可以使用strip实用程序轻松地剥离调试信息,以生成与未使用-g标志编译的二进制文件相同的二进制文件。

通常情况下,当你想要调试的东西,你将编译没有优化和NDEBUG预处理器宏。但是,这些东西不是由-g标志控制的。

如果您在调试器外运行它不会有任何性能影响。调试符号是用来帮助调试的。在这两种情况下生成的代码应该是相同的。

相关文章: