剖析 C + + 编译过程

我倾向于编写相当大的模板化的只有标题的 C + + 库,我的用户经常抱怨编译时间。在思考了这件事之后,我突然想到 我不知道时间会流逝到哪里。是否有一些简单的方法来分析 C + + 编译过程与公共编译器,如 海湾合作委员会(g++) ,Intel C++编译器(icc)和 XL C/C + + (xlC) ?例如,有没有可能知道在 C + + 编译的每个阶段中花费了多少时间?

21860 次浏览

You can separate them out to some extent (I'm assuming Make)

  • add a build rule that only preprocesses files (using the -E switch), and a .PHONY target that depends on the preprocessor output files just like the normal binary target depends on .o files. Measure how long it takes to build this target
  • add a 'PHONY target that depends on all the .o files, but doesn't link them. Measure how long it takes to build this target (from clean)
  • measure how long it takes to do a clean build of the usual binary

Now you have some idea how long it takes to pre-process, compile, and link. You can also compare optimized and non-optimized (-O0) versions of the second and third target, to see how long is spent in the optimizer.

You might be able to get some traction with some variant on strace -e trace=process -f -r -ttt -T, at least for compilers like g++ that are broken up into many processes.

There's a tool from the Boost project, which could be useful for pretty much any compiler and build system.

The tool requires source code instrumentation with TEMPLATE_PROFILE_ENTER() and TEMPLATE_PROFILE_EXIT() macro calls. These macros then generate specific diagnostics (warnings) at compile-time, which are timed and collected along with instantiation callstacks (which consequently allow building and visualizing callgraphs) by a script. Not bad, IMO.

I didn't use it yet though.

For GCC there are debugging options to find how much time is spent within each of the phases of C++ compilation?

-Q Makes the compiler print out each function name as it is compiled, and print some statistics about each pass when it finishes.

-ftime-report Makes the compiler print some statistics about the time consumed by each pass when it finishes.

Passes are described in GCCINT 9: Passes and Files of the Compiler.

You can post output of g++ compilation of single source file with -v -ftime-report here to discuss it. There could be some help on the GCC mailing list.


For compilers other than GCC (or GCC more ancient than 3.3.6), see the other options in other answers.

Others have already suggested the -ftime-report command line flag for GCC, which makes the compiler print some statistics about the time consumed by each compilation phase. The drawback is that it only shows summary for one unit.

I've written a Python script, which allows to print the total summary on all units, by each compilation phase, given the project build log file. It also allows sorting by different phases. And it also allows to compare two log files (e.g., if you're trying to understand the impact of your changes).

Clang 9 (and newer) has a -ftime-trace flag, which makes it output a profiling report as JSON (in addition to an object file).

You can import this file into a profiler that comes with Chrome (chrome://tracing) to get a nice visualisation:

pic

The bars correspond to headers that had to be parsed, and for each header, specific classes (and probably other constructs) that had to be parsed. It also reports time spent on instantiating specific templates.

Externis is a GCC plugin that will generate trace files very similar to Clang's -ftime-trace:

Enter image description here

Disclaimer: I'm the author of this plugin.