(这是关于gcc和clang的问题,但可能适用于其他编译器。)
如果我编译我的C或C ++代码,并使用-g
开关生成调试信息,这本身是否会以任何方式降低编译程序的性能......(1。)最小化优化({} {1}})? (2.)最大化优化(-O0
)?
注意:我并不意味着必须解析/加载可执行文件的性能损失,由于额外的内容,这可能会更大;我的意思是代码运行。
答案 0 :(得分:7)
我认为没有任何性能差异。实际上,根据文档here,生成的代码将是相同的,-g
可用于-O
。此外,调试符号不会写入代码,而是写入另一个称为“调试部分”的部分,该部分甚至不在运行时加载(仅由调试器加载)
-g
不会更改运行的优化或代码生成。
这是gcc政策,如here
但是,注意相同的文档说明:
可能有用优化代码所采用的快捷方式有时可能会令人惊讶: 您声明的某些变量可能根本不存在;控制流程可以 短暂地移动到你没想到的地方;有些陈述可能不是 执行,因为他们计算常量结果或其值 已经在手;某些陈述可能在不同的地方执行 因为他们已经被移出了循环。不过有可能 调试优化输出。这使得合理使用 可能存在错误的程序的优化器。
所以最后调试永远不会损害你的优化,但相反的是假的,使用-O3
可能会降低你的调试信息(例如删除无用的变量)。
请注意,在这种情况下使用-Og
(如here所述)可能会更好,因为它会:
优化调试体验。 -Og启用不优化的优化 干扰调试。它应该是优化级别 选择标准的编辑 - 编译 - 调试周期,提供一个 合理的优化级别,同时保持快速编译 和良好的调试经验。
然而,这会影响性能,因为一些会干扰调试的优化过程将无法完成。
编辑:
链接和引文会回答您gcc
的问题。它可能不适用于其他编译器,例如clang
。
但是我找到了clang
的一些文档。
例如here:
基本上,调试信息允许您使用编译程序 “-O0 -g”并获得完整的调试信息,允许您任意 从调试器执行时修改程序。编译程序 使用“-O3 -g”可以获得始终完整的调试信息 可用且准确的读数(例如,您获得准确的堆栈 尽管尾部呼叫消除和内联仍然存在,但您可能会失败 修改程序和调用函数的能力 优化了程序,或完全内联。
答案 1 :(得分:2)
-g标志将调试信息添加到二进制文件中。这存在于.stab
CPU运行位的可执行文件的单独部分(.stabstr
和.text
)中。在调试器外部运行时,操作系统加载程序不会加载调试部分。使用strip
实用程序也可以轻松地删除调试信息,以生成与没有-g标志编译的二进制文件相同的二进制文件。
但是,通常情况下,当您想要调试内容时,您将在没有优化的情况下编译并使用NDEBUG预处理器宏。但是这些东西不受-g标志控制。
答案 2 :(得分:-1)
如果在调试器外运行它,就不会有任何性能损失。调试符号有助于调试。在两种情况下生成的代码都应相同。