18

我有一个巨大的项目,大约 150 000 LOC 的 C++ 代码。构建时间大约是 15 分钟。该项目由许多不同规模的子项目组成。

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

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

我所有的预编译头文件都不是很大,每个文件大约 50Mb。我使用 python 脚本,在这里找到来生成最常用的预编译头列表,所以我的预编译候选列表非常好。

是否有任何免费/开源工具可用于构建优化?似乎标准make实用程序无法测量不同目标的构建时间。我找不到使用make. 我不是在谈论依赖分析或高级的东西。我只想知道大部分时间浪费在哪些目标上。

此外,GCC 在处理预编译头文件方面似乎效率很低。我无法使任何子项目的构建速度显着加快,在一个构建时间为三分钟的项目上,我获得的最大加速是 20%。与使用 GCC 在 linux 上优化构建时间相比,购买更快的带有固态驱动器的机器似乎更容易、更便宜。

4

4 回答 4

11

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,这会花费更多时间阅读 makefile 和重新创建依赖关系图。如果您可以构建您的子项目 makefile 以便它们都可以包含在单个顶级 makefile 中,那么非递归 make 将需要更长的时间才能开始,但一旦开始构建目标就会运行。不过,重写 makefile 可能需要做很多工作。

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

于 2012-11-13T01:09:24.990 回答
6

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

您可以设置一个包含目标的持续集成系统,以衡量和记录您的进度/改进,因为您的更改进入。

我有一个巨大的项目,大约 150 000 LOC 的 C++ 代码。构建时间大约是 15 分钟。该项目由许多不同规模的子项目组成。

假设你有一台现代机器,听起来它做了很多多余的工作。

还要考虑链接时间。

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

这是相当大的,IMO。

我不是在谈论依赖分析或高级的东西。

同样,统计数据的持续集成。对于缓慢的构建,过度依赖很可能是问题所在(除非您有很多很多小的 cpp 文件,或者正在发生诸如物理内存耗尽之类的愚蠢事情)。

我无法使任何子项目的构建速度明显更快,我得到的最大加速是 20%

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

与使用 GCC 在 linux 上优化构建时间相比,购买更快的带有固态驱动器的机器似乎更容易、更便宜。

很有可能,这台机器不会让你的构建时间快 20 倍,但是修复你的依赖项和项目结构可以让它快 20 倍(或者不管问题的根源是什么)。这台机器的帮助只有这么多(考虑到 150KSLOC 的构建时间)。

您的构建可能受 CPU/内存限制。

于 2012-11-12T07:29:10.343 回答
0

我在生成和使用 PCH 时使用 -include 来包含包含大量标头的文件。它有帮助,但仍然没有那么令人印象深刻。

不过,算你的福气:gcc 似乎比 MSVC 快好几倍,尽管 MSVC 有更好的 PCH 支持。

于 2012-11-13T04:13:57.793 回答
0

目前我正在尝试改善我的项目构建时间。该项目使用 CMake 和 GCC,大约 100K LOC,使用 Boost。

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

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

于 2020-05-16T15:57:52.800 回答