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

C++ 使用-g gcc标志编译的程序是否比不使用-g标志编译的程序慢?,c++,debugging,gcc,optimization,C++,Debugging,Gcc,Optimization,我正在编译一个程序,其中-O3表示性能,-g表示调试符号(在崩溃的情况下,我可以使用核心转储)。有一件事让我很困扰,-g选项会导致性能下降吗?当我查看带-g和不带-g编译的输出时,我发现不带-g的输出比带-g编译的输出小80%。如果额外的空间用于调试符号,我不在乎(我猜),因为这部分在运行时没有使用。但是如果对于没有-g的编译输出中的每条指令,我需要在编译输出中使用-g执行4条以上的指令,那么我当然更愿意停止使用-g选项,即使代价是无法处理核心转储 如何知道程序中调试符号部分的大小,以及通常使用

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

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

引用

GCC允许您将-g与-O一起使用 代码有时可能会产生令人惊讶的结果:一些变量 声明可能根本不存在;控制流可能会短暂移动到以下位置: 你没有预料到;某些语句可能无法执行,因为 他们计算不变的结果或者他们的值已经在手边了; 有些语句可能在不同的位置执行,因为它们已被删除 从循环中移出

这意味着:

我将为您插入调试符号,但我不会尝试保留它们。如果优化过程使它们失效,您将不得不处理这些问题

调试符号不会写入代码,而是写入另一个名为“调试部分”的部分,该部分甚至在运行时都没有加载(仅由调试器加载)。这意味着:没有代码更改。您不应该注意到代码执行速度上的任何性能差异,但是如果加载程序需要处理较大的二进制文件,或者考虑到增加的二进制文件大小,您可能会遇到一些缓慢的情况。您可能需要自己对应用程序进行基准测试,才能100%确定您的具体情况

请注意,gcc 4.8中还有:

-Og

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

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


最后,有些优化更适合于特定的体系结构,而不是另一个体系结构,这可能是甚至的情况,除非指示您针对特定的处理器这样做(请参阅体系结构的选项),否则在O3中,gcc将对通用体系结构发挥最大作用。这意味着在某些人为的情况下,你甚至可能会体验到O3比O2慢。“尽力而为”并不总是意味着“最佳可用”。

你对它进行了基准测试吗?对这个项目进行基准测试并不容易,真的,如果很容易做到,我不会问这个问题,我会自己衡量惩罚。我已经衡量过了。看起来他们跑的速度一样
-g
只添加调试符号。显然,这取决于您的程序。MSVC使用单独的存储调试符号,您甚至可以在发布模式下进行调试,因此有时您甚至会遇到一个优化过的变量,并且它的值未定义。我不知道gcc是否有类似的选项FWIW,您甚至可以指定如何实现这一点,即
march
mtune
。请注意,即使您确实注意到由于
-g
导致的性能差异,也可以使用
objcopy--strip debug
objcopy--keep debug
将调试信息移动到单独的文件中。