使用GCC编译时,理解编译时间消耗的位置

17

我有一个大量使用模板的项目。最近,编译时间突然增加了很多。我想知道是否有一种方法可以查看哪些类/行需要使用g++编译所需的最长时间。

这里是一些来自-ftime-report的输出:

Execution times (seconds)
 TOTAL                 :   0.30             0.05             0.37               9119 kB

Execution times (seconds)
 garbage collection    :   0.91 ( 6%) usr   0.00 ( 0%) sys   0.92 ( 5%) wall       0 kB ( 0%) ggc
 callgraph construction:   0.23 ( 2%) usr   0.11 ( 3%) sys   0.37 ( 2%) wall   10652 kB ( 1%) ggc
 callgraph optimization:   0.18 ( 1%) usr   0.12 ( 3%) sys   0.28 ( 2%) wall   11906 kB ( 2%) ggc
 varpool construction  :   0.04 ( 0%) usr   0.01 ( 0%) sys   0.08 ( 0%) wall    6984 kB ( 1%) ggc
 cfg construction      :   0.03 ( 0%) usr   0.00 ( 0%) sys   0.05 ( 0%) wall     644 kB ( 0%) ggc
 cfg cleanup           :   0.05 ( 0%) usr   0.02 ( 0%) sys   0.05 ( 0%) wall       7 kB ( 0%) ggc
 trivially dead code   :   0.05 ( 0%) usr   0.01 ( 0%) sys   0.12 ( 1%) wall       0 kB ( 0%) ggc
 df scan insns         :   0.37 ( 3%) usr   0.03 ( 1%) sys   0.43 ( 2%) wall     677 kB ( 0%) ggc
 df live regs          :   0.07 ( 0%) usr   0.01 ( 0%) sys   0.02 ( 0%) wall       0 kB ( 0%) ggc
 df reg dead/unused notes:   0.08 ( 1%) usr   0.01 ( 0%) sys   0.08 ( 0%) wall    2755 kB ( 0%) ggc
 register information  :   0.05 ( 0%) usr   0.01 ( 0%) sys   0.05 ( 0%) wall       0 kB ( 0%) ggc
 alias analysis        :   0.01 ( 0%) usr   0.01 ( 0%) sys   0.01 ( 0%) wall     878 kB ( 0%) ggc
 rebuild jump labels   :   0.03 ( 0%) usr   0.01 ( 0%) sys   0.01 ( 0%) wall       0 kB ( 0%) ggc
 preprocessing         :   0.19 ( 1%) usr   0.44 (11%) sys   0.68 ( 4%) wall    5284 kB ( 1%) ggc
 parser                :   3.94 (28%) usr   1.43 (35%) sys   4.94 (27%) wall  355964 kB (48%) ggc
 name lookup           :   1.35 ( 9%) usr   0.88 (21%) sys   2.76 (15%) wall   64919 kB ( 9%) ggc
 inline heuristics     :   0.14 ( 1%) usr   0.03 ( 1%) sys   0.14 ( 1%) wall       0 kB ( 0%) ggc
 integration           :   0.02 ( 0%) usr   0.00 ( 0%) sys   0.02 ( 0%) wall      20 kB ( 0%) ggc
 tree gimplify         :   0.31 ( 2%) usr   0.07 ( 2%) sys   0.28 ( 2%) wall   24598 kB ( 3%) ggc
 tree eh               :   0.07 ( 0%) usr   0.02 ( 0%) sys   0.11 ( 1%) wall    7267 kB ( 1%) ggc
 tree CFG construction :   0.04 ( 0%) usr   0.04 ( 1%) sys   0.11 ( 1%) wall   15754 kB ( 2%) ggc
 tree CFG cleanup      :   0.12 ( 1%) usr   0.00 ( 0%) sys   0.05 ( 0%) wall       3 kB ( 0%) ggc
 tree find ref. vars   :   0.03 ( 0%) usr   0.01 ( 0%) sys   0.02 ( 0%) wall     963 kB ( 0%) ggc
 tree PHI insertion    :   0.00 ( 0%) usr   0.01 ( 0%) sys   0.01 ( 0%) wall     351 kB ( 0%) ggc
 tree SSA rewrite      :   0.03 ( 0%) usr   0.01 ( 0%) sys   0.01 ( 0%) wall    4078 kB ( 1%) ggc
 tree SSA other        :   0.03 ( 0%) usr   0.06 ( 1%) sys   0.12 ( 1%) wall    1504 kB ( 0%) ggc
 tree operand scan     :   0.04 ( 0%) usr   0.02 ( 0%) sys   0.08 ( 0%) wall   10781 kB ( 1%) ggc
 dominance computation :   0.15 ( 1%) usr   0.04 ( 1%) sys   0.15 ( 1%) wall       0 kB ( 0%) ggc
 out of ssa            :   0.09 ( 1%) usr   0.00 ( 0%) sys   0.02 ( 0%) wall       0 kB ( 0%) ggc
 expand vars           :   0.03 ( 0%) usr   0.00 ( 0%) sys   0.03 ( 0%) wall    1840 kB ( 0%) ggc
 expand                :   0.45 ( 3%) usr   0.04 ( 1%) sys   0.59 ( 3%) wall   37695 kB ( 5%) ggc
 post expand cleanups  :   0.08 ( 1%) usr   0.02 ( 0%) sys   0.06 ( 0%) wall    4542 kB ( 1%) ggc
 varconst              :   0.15 ( 1%) usr   0.03 ( 1%) sys   0.12 ( 1%) wall    3595 kB ( 0%) ggc
 jump                  :   0.01 ( 0%) usr   0.00 ( 0%) sys   0.04 ( 0%) wall    1904 kB ( 0%) ggc
 mode switching        :   0.01 ( 0%) usr   0.00 ( 0%) sys   0.01 ( 0%) wall       0 kB ( 0%) ggc
 integrated RA         :   1.33 ( 9%) usr   0.09 ( 2%) sys   1.49 ( 8%) wall   18163 kB ( 2%) ggc
 reload                :   0.60 ( 4%) usr   0.10 ( 2%) sys   0.62 ( 3%) wall    8668 kB ( 1%) ggc
 thread pro- & epilogue:   0.17 ( 1%) usr   0.00 ( 0%) sys   0.20 ( 1%) wall   11884 kB ( 2%) ggc
 reg stack             :   0.02 ( 0%) usr   0.00 ( 0%) sys   0.00 ( 0%) wall       0 kB ( 0%) ggc
 final                 :   0.71 ( 5%) usr   0.10 ( 2%) sys   0.84 ( 5%) wall    6251 kB ( 1%) ggc
 symout                :   1.10 ( 8%) usr   0.16 ( 4%) sys   1.19 ( 6%) wall  100954 kB (14%) ggc
 uninit var analysis   :   0.03 ( 0%) usr   0.00 ( 0%) sys   0.01 ( 0%) wall       0 kB ( 0%) ggc
 early local passes    :   0.00 ( 0%) usr   0.00 ( 0%) sys   0.01 ( 0%) wall       0 kB ( 0%) ggc
 rest of compilation   :   0.49 ( 3%) usr   0.06 ( 1%) sys   0.76 ( 4%) wall   19252 kB ( 3%) ggc
 unaccounted todo      :   0.43 ( 3%) usr   0.09 ( 2%) sys   0.55 ( 3%) wall       0 kB ( 0%) ggc
 TOTAL                 :  14.26             4.11            18.52             742072 kB

你需要提供比这更多的信息。如果没有任何东西可以查看,我们很难提供帮助。 - Mysticial
1
你可以尝试编译不同的版本,看看何时出现时间增加;然后查看该版本中发生了哪些更改,以便帮助你理解。 - mparizeau
也许值得看一下这个帖子https://dev59.com/GHI95IYBdhLWcg3w-DBb - daz-fuller
可能是调试GCC编译时间的重复问题。 - devnull
3个回答

12

Steven Watanabe的模板分析器可以帮助您获取每个类/函数实例化计数。

请查看调试GCC编译时间,了解此工具的实际链接。


现在,人们也可以使用更好的clang 9 -ftime-trace选项。 - Joel Falcou

7

当我看到您在项目中广泛使用了模板时,我首先怀疑的是模板实例化。在看到以下信息后,我的怀疑变得更强:

parser       : ... (27%) wall 355964 kB (48%) ggc
name lookup  : ... (15%) wall 64919 kB ( 9%) ggc

由于我无法看到代码(因为您没有发布它),所以我只能猜测。我的第二个猜测是,您没有使用模板的显式实例化来处理已知类型(您肯定会使用这些类型),而是依赖于隐式实例化并且您正在从许多.cpp文件中使用模板。如果是这样,那么这可能是主要问题,因为隐式实例化导致同一模板被实例化多次,每个翻译单元一次。因此,如果您有M个模板,并且您从N个翻译单元(.cpp)中使用它,则将有M * N个实例化,而不仅仅是M个实例化。


1
非常感谢。这是一个案例,同样的模板类在许多 .cpp 文件中实例化。我会尝试找出需要最长时间的模板类,并进行修改。 - Fabio Dalla Libera

1

据我所知,目前没有这样的编译开关存在。

更手动的方法是将预处理和编译分开(gcc -E,然后在预处理文件上运行gcc -c),以猜测时间花费在哪里。

另一种解决方案是对构建环境进行仪器化,以获得每个文件的编译时间。请注意,我只能建议设置持续集成来及早跟踪这些演变(一旦它出现,您就可以检测到它,而无需挖掘过去引入跳跃的原因)。

作为经验法则,您可以检查是否只包含相关标头(尝试删除一些)或切换到预编译标头。


非常感谢。 我已经有了哪些文件需要最长的编译时间的想法。正如你所指出的那样,这些文件包含大部分头文件。 我尝试过使用预编译头文件,但是并没有得到很高的速度提升(我仍然不知道为什么)。只有ccache给了我速度上的提升。 - Fabio Dalla Libera
使用 -Q 选项,我发现大部分时间都花在了解析器上。但我不知道这意味着什么可疑的代码。 - Fabio Dalla Libera
在Mac OS X上的/usr/bin/gcc中存在选项-ftime-report-- i686-apple-darwin11-llvm-gcc-4.2(GCC)4.2.1(基于Apple Inc. build 5658)(LLVM build 2335.15.00)。更详细的报告似乎来自/usr/bin/clang-- Apple clang version 2.1(tags/Apple/clang-163.7.1)(基于LLVM 3.0svn)。它可能是clang的一个选项,或者它可能只是在较新版本的GCC中的一个选项。 - Jonathan Leffler
谢谢你,-ftime-report 在 g++ 中存在,但它只提供了帖子中所见的内容。 - Fabio Dalla Libera

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接