使用-g本身进行编译是否会降低性能?
Does compiling with -g, in itself, degrade performance?
(这是一个关于gcc和clang的问题,但可能适用于其他编译器)
如果我编译我的C或c++代码,并使用-g
开关生成调试信息,这本身是否会以任何方式降低编译程序的性能…
- 最小优化(
-O0
)? - 最大优化(
-O3
)?
注意:我不是指必须解析/加载可执行文件的性能损失,由于额外的内容,这是较大的;我指的是运行的代码
我不认为有任何性能差异。实际上,生成的代码是相同的,根据这里的文档,-g
可以与-O
一起使用。此外,调试符号不会写入代码,而是写入另一个称为"调试段"的部分,该部分甚至不会在运行时加载(仅由调试器加载)
-g
不会改变运行的优化或生成的代码。
然而,可能需要注意的是,同一文档声明:
优化后的代码所采用的快捷方式有时会令人惊讶:你声明的一些变量可能根本不存在;控制流程可能短暂地移动到你没有预料到的地方;有些陈述可能不是执行是因为它们计算常数结果或它们的值是已经在手边的;有些语句可能在不同的地方执行因为它们被移出了循环。然而,这是可能的调试优化的输出。这使得使用为可能存在错误的程序提供优化器。
所以最后的调试永远不会损害你的优化,但相反是假的,使用-O3
可能会降低你的调试信息(通过删除无用的变量,例如)。
请注意,在这种情况下使用-Og
(如这里所述)可能会更好,因为它将:
优化调试体验。-Og允许不需要的优化干扰调试。它应该是的优化级别选择标准的编辑-编译-调试周期,提供一个合理的优化水平,同时保持快速编译以及良好的调试体验。
然而,这将影响性能,因为一些会干扰调试的优化传递将不会完成。
编辑:
链接和引号回答了gcc
的问题。它可能不适用于其他编译器,如clang
。然而,我也发现了一些clang
的文档。例如:
基本上,调试信息允许你编译一个程序" - 0 -g "并获得完整的调试信息,允许您任意调试在程序从调试器执行时修改程序。编译程序使用"-O3 -g"为您提供完整的调试信息可用和准确的读取(例如,你得到准确的堆栈踪迹,尽管尾部呼叫消除和内联),但你可能会输修改程序和调用函数的能力在程序外优化,或者完全内联。
-g标志向二进制文件中添加调试信息。它存在于.text
CPU运行位的可执行文件的单独部分(.stab
和.stabstr
)中。当在调试器外运行时,操作系统加载程序不会加载调试部分。也可以使用strip
实用程序轻松地剥离调试信息,以生成与未使用-g标志编译的二进制文件相同的二进制文件。
通常情况下,当你想要调试的东西,你将编译没有优化和NDEBUG预处理器宏。但是,这些东西不是由-g标志控制的。
如果您在调试器外运行它不会有任何性能影响。调试符号是用来帮助调试的。在这两种情况下生成的代码应该是相同的。
- 是否总是可以将使用递归编写的程序重写为不使用递归的程序C++,性能观点是什么?
- 不同版本的编译器(例如GCC)是否会产生不同的性能?
- 在现代C++中,侵入式容器是否仍然比非侵入式容器具有性能优势?
- 与纯 V8 相比,NodeJS 是否有任何性能缺陷或显著开销?
- 通过默认复制构造函数比较 C++ 字符串是否会影响性能,原因为何?
- 隐式转换函数的返回对象时是否会影响性能?
- 为数组赋值时是否存在性能差异
- 在类中始终使用此指针是否有任何性能成本
- 在渲染之前直接上传是否会对性能产生负面影响
- 我是否错过了什么,或者虚拟呼叫的性能并不像人们所说的那样糟糕
- 使用 OpenGL 窗口(如 GLFW)或周围的窗口(如 GTK 或 SDL)是否存在性能差异?
- 在将其尺寸较大的向量移动到容量较小的向量之前,是否可以通过使用Reserve()来提高代码性能
- QSqlQuery 绑定值与 BindValues 与 QString.arg() 是否存在性能差异
- 检查从查询返回的任何行是否包含在字符串中的最高性能方法?
- 在C++代码中使用纯 C 库是否有性能下降/损失
- 使用 const CString& 而不是单独使用 CString 作为函数参数是否有任何性能优势?
- 在 C/C++ 中在特定地址边界上对齐内存是否仍能提高 x86 性能?
- 如果多个线程使用同一对象,性能是否受到影响
- OpenCV的Python或C++编码的性能是否不同
- 当从应用程序多次调用数据库过程时,性能是否会受到影响