在分析代码时,我应该使用匹配(gcc)编译器优化标志吗

Should I use matching (gcc) compiler optimization flags when profiling the code?

本文关键字:gcc 编译器 标志 优化 代码 我应该      更新时间:2023-10-16

我在编译代码时使用-O3,现在我需要对其进行评测。对于评测,我遇到了两个主要选择:valgrind--tool=callgrind和gprof。

Valgrind(callgrind)文档状态:

与Cachegrind一样,您可能希望在编译时使用调试信息(-g选项)并打开优化。

然而,在Agner Fog的C++优化书中,我读到了以下内容:

许多优化选项与调试不兼容。调试器可以执行每次编写一行代码并显示所有变量的值。显然,这是不可能的当部分代码被重新排序、内联或优化掉时。常见于使程序的两个版本可执行:具有完全调试支持的调试版本在程序开发过程中使用的,以及具有所有相关功能的发布版本优化选项已打开。大多数IDE(集成开发环境)都有用于制作对象文件和可执行文件的调试版本和发布版本的工具。请确保区分这两个版本,并在中关闭调试和分析支持可执行文件的优化版本。

这似乎与编译代码的callgrind指令与调试信息标志-g相冲突。如果我以以下方式启用调试:

-ggdb -DFULLDEBUG

我是否导致此选项与-O3优化标志冲突?在我读了这么多之后,把这两个选项放在一起对我来说毫无意义。

如果我使用比如-O3优化标志,我可以使用编译带有额外分析信息的代码吗

-pg

仍然用valgrind来描述它?

评测用编译的代码有意义吗

-ggdb -DFULLDEBUG -O0

旗帜?这似乎很愚蠢——不内联函数和展开循环可能会改变代码中的瓶颈,所以这应该只用于开发,以使代码真正正确地执行。

用一个优化标志编译代码,并用另一个优化标记编译代码,这有意义吗?

为什么要进行分析?只是为了测量还是为了寻找加速?

人们普遍认为,应该只评测优化的代码,这是基于假设代码一开始几乎是最优的,如果有显著的加速,那就不是了。

你应该像对待bug一样对待加速的发现。许多人使用这种方法这样做。

在您删除了不必要的计算之后,如果您仍然有紧张的CPU循环,即您没有将所有时间都花在优化器看不到的系统、库或i/O例程中,那么打开-O3,让它发挥它的魔力。