使用-g gcc标志编译的程序比不使用-g编译的程序慢

Is a program compiled with -g gcc flag slower than the same program compiled without -g?

本文关键字:程序 编译 gcc 使用 标志      更新时间:2023-10-16

我正在编译一个程序,其中-O3用于性能,-g用于调试符号(如果发生崩溃,我可以使用核心转储)。有一件事让我很困扰,-g选项会导致性能损失吗?当我查看带-g和不带-g的编译输出时,我发现不带-g的输出比带-g的编译输出小80%。如果额外的空间用于调试符号,我不关心它(我猜),因为这部分在运行时不使用。但是,如果对于没有-g的编译输出中的每条指令,我需要在有-g的编译输出中多执行4条指令,那么我当然更愿意停止使用-g选项,即使无法处理核心转储。

如何知道程序内调试符号部分的大小,通常使用-g编译会创建一个运行速度比不使用-g编译的相同代码慢的程序?

引用自gcc文档

GCC允许您将-g与-O一起使用。所采取的快捷方式得到了优化代码有时可能会产生令人惊讶的结果:一些变量您无法使用声明的可能根本不存在;控制流可能会短暂地移动到哪里你没有预料到;有些语句可能不会执行,因为它们计算恒定的结果,或者它们的值已经在手边;有些语句可能在不同的位置执行,因为它们曾经在不同的位置执行过移出循环。

意思是:

我将为你插入调试符号,但我不会试图保留它们,如果一个优化过程把它们弄掉了,你必须处理

调试符号不会写入代码,而是写入另一个称为"调试段"的部分,该部分甚至不会在运行时加载(仅由调试器加载)。这意味着:没有代码更改。您不应该注意到代码执行速度的任何性能差异,但如果加载程序需要处理更大的二进制文件,或者如果它以某种方式考虑到二进制文件大小的增加,则可能会遇到一些慢。你可能需要自己对应用程序进行基准测试,以便在特定情况下100%确定。

注意,gcc 4.8中还有另一个选项:

-Og

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

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

最后,甚至可能会发生一些优化更适合于特定的体系结构而不是另一个体系结构,除非您的特定处理器指示这样做(请参阅您的体系结构的march/mtune选项),在O3中,gcc将对通用体系结构进行最佳的。这意味着在某些人为的场景中,您甚至可能会遇到O3比O2慢的情况。"尽力而为"并不总是意味着"尽力而为"。