GCC的构建时间不会从预编译的头文件中受益很多

问题描述 投票:16回答:4

我有一个庞大的项目,大约15万个C ++代码的LOC。构建时间约为15分钟。该项目由许多不同大小的子项目组成。

我为每个子项目构建了单独的预编译头,但是当我使用它们时,构建时间保持大致相同。似乎构建时间减少了5-10%,而不是更多。

肯定使用了预编译头,我使用-Winvalid-pch选项,并且尝试使用-H编译器选项进行编译,我的预编译头出现在输出中并带有'bang'符号,​​这意味着编译器可以使用预编译头。

我所有的预编译头文件都不是很大,每个文件大约50Mb。我使用python脚本,发现here生成最常用的预编译头列表,因此我的预编译候选列表非常好。

是否有任何免费/开源工具可用于构建优化?似乎标准的make实用程序无法测量不同目标的构建时间。我找不到用make获取不同目标的统计信息的方法。我不是在谈论依赖性分析或高级的东西。我只想知道大多数时间都浪费了什么目标。

而且,GCC在处理预编译的标头时似乎效率很低。我无法使任何子项目的构建速度都显着提高,在要构建三分钟的项目上,我获得的最大加速是20%。与使用GCC在Linux上优化构建时间相比,购买具有固态驱动器的计算机似乎更容易,更便宜。

c++ gcc build-process gnu-make precompiled-headers
4个回答
6
投票

如果您想充分利用此功能,则需要了解如何构造项目以充分利用它们。最好的方法是手动减少构建时间的缓慢而艰苦的过程。一开始听起来确实很愚蠢,但是如果所有构建的速度都快了5倍,并且您知道如何构建项目和依赖关系,那么您就会体会到回报。

您可以为目标设置一个持续集成系统,以在进行更改时衡量并记录您的进度/改进。

我有一个庞大的项目,大约15万个C ++代码的LOC。构建时间约为15分钟。该项目由许多不同大小的子项目组成。

听起来好像在做很多多余的工作,假设您有一台现代化的机器。

也请考虑链接时间。

我所有的预编译头文件不是很大,每个文件约为50Mb。

相当大,IMO。

我不是在谈论依赖性分析或其他高级内容。

再次,进行统计的持续集成。对于构建缓慢,过分依赖的构建,很可能会出现此问题(除非您有许多小cpp文件,或者发生诸如物理内存耗尽之类的愚蠢行为)。

我无法使任何子项目的构建速度显着提高,我获得的最大提速是20%

了解您的结构和依赖性。 PCH减慢了我的大部分项目。

[似乎比使用GCC在Linux上优化构建时间来购买具有固态驱动器的机器更快,更便宜。

机会是,这台机器不会使您的构建时间快20倍,但是修正您的依赖关系和项目结构可以使其构建速度快20倍(或问题的根本根源是什么)。该机器仅提供了很多帮助(考虑到150KSLOC的构建时间)。

您的版本可能受CPU /内存限制。


10
投票

GCC构建时间从预编译的头文件中受益不多

是的,不幸的是,通常是这样,

有一些实验项目可以做得更好,请参阅http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3426.htmlhttp://gcc.gnu.org/wiki/pph,但它们尚不可用。

我同意另一个答案,即150KLOC的15分钟相当慢。

[我发现使用Gold链接器在构建时间上有很大的不同,我强烈建议这样做。

您也可以考虑使用ccache会有所帮助,如果您在其他计算机上有备用循环distcc

[避免在慢速磁盘上构建,当然要避免网络磁盘。避免进行递归调用make,因为make会花费更多时间读取makefile和重新创建依赖关系图。如果可以构造子项目的makefile,以便所有这些文件都可以包含在单个顶级makefile中,那么非递归的make会花一点时间才能上手,但是一旦开始构建目标就可以运行。不过,重写makefile可能需要大量工作。

[这可能不言而喻,但是要在多核计算机上构建并使用make -j N,其中一个好的经验法则是N应该是核数的两倍,如果编译受I / O限制,则应该更多。


0
投票

我在生成并使用PCH包含一个包含很多头的文件时使用-include。它有帮助,但仍然不那么令人印象深刻。

尽管,算上您的祝福:即使MSVC具有更好的PCH支持,gcc也似乎比MSVC快几倍。


0
投票

目前,我正在尝试缩短项目的构建时间。该项目使用CMake和GCC,使用Boost大约有10万个LOC。

通过切换到预编译的头文件,我设法将构建机器上的构建时间从43分钟缩短到35分钟。我使用了-ftime-report GCC标志来获取每个编译阶段的时间,并且我还使用了辅助Python script来汇总所有编译单元的时间。

这些时间帮助我理解了,将预编译的标头添加到项目中可能会大大减少解析和预处理阶段,但同时可能会大大增加代码生成和优化阶段。这是因为您将所有预编译的头数据添加到每个编译单元,并且编译器现在也需要处理该数据。根据这两个贡献,您可能会或不会从使用预编译头中获得好处。

© www.soinside.com 2019 - 2024. All rights reserved.