本文介绍了如何加快启用 CMake 的 C++ 项目的编译时间?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近遇到了几个关于改进启用 CMake 的 C++ 项目的周转时间的特定方面的 SO 问题(例如 我应该在什么级别分发我的构建过程?""cmake rebuild_cache 只是 一个子目录?"),我想知道是否有利用 CMake 提供的特定可能性的更一般的指导.如果可能没有跨平台编译时间优化,我主要对基于 Visual Studio 或 GNU 工具链的方法感兴趣.

I came across several SO questions regarding specific aspects of improving the turn-around time of CMake enabled C++ projects lately (like "At what level should I distribute my build process?" or "cmake rebuild_cache for just a subdirectory?"), I was wondering if there is a more general guidance utilizing the specific possibilities CMake offers. If there is probably no cross-platform compile time optimization, I'm mainly interested in Visual Studio or GNU toochain based approaches.

而且我已经知道并投资于通常推荐的领域以加速 C++ 构建:

And I'm already aware of and investing into the generally recommended areas to speed up C++ builds:

  1. 更改/优化/微调工具链

  1. Change/Optimize/fine-tune the toolchain

优化您的代码库/软件架构(例如,通过减少依赖项并使用定义明确的子项目 - 单元测试)

Optimize your code base/software architecture (e.g by reducing the dependencies and use well-defined sub-projects - unit tests)

投资更好的硬件(SSD、CPU、内存)

Invest in a better hardware (SSD, CPU, memory)

喜欢推荐的这里, 这里这里.所以我在这个问题上的重点是第一点.

like recommended here, here or here. So my focus in this question is on the first point.

另外,我知道在 CMake 的 Wiki 中可以找到的建议:

Plus I know of the recommendations to be found in CMake's Wiki:

前者只处理基础(并行make),后者主要处理如何加速解析CMake文件.

The former just handles the basics (parallel make), the later handles mostly how to speed-up parsing CMake files.

只是为了让这更具体一点,如果我从 此处 使用 MSYS/GNU 的 100 个库我得到了以下 time 测量结果:

Just to make this a little more concrete, if I take my CMake example from here with 100 libraries using MSYS/GNU I got the following time measurement results:

$ cmake --version
cmake version 3.5.2
CMake suite maintained and supported by Kitware (kitware.com/cmake).

$ time -p cmake -G "MSYS Makefiles" ..
-- The CXX compiler identification is GNU 4.8.1
...
-- Configuring done
-- Generating done
-- Build files have been written to: [...]
real 27.03
user 0.01
sys 0.03

$ time -p make -j8
...
[100%] Built target CMakeTest
real 113.11
user 8.82
sys 33.08

所以我总共有大约 140 秒,我的目标 - 对于这个公认的非常简单的例子 - 是将其降低到我使用标准设置/工具获得的大约 10-20%.

So I have a total of ~140 seconds and my goal - for this admittedly very simple example - would be to get this down to about 10-20% of what I get with the standard settings/tools.

推荐答案

以下是我使用 CMake 和 Visual Studio 或 GNU 工具链取得的良好结果:

Here's what I had good results with using CMake and Visual Studio or GNU toolchains:

  1. Ninja 交换 GNU make.它速度更快,自动使用所有可用的 CPU 内核,并且具有良好的依赖性管理.只要注意

  1. Exchange GNU make with Ninja. It's faster, makes use of all available CPU cores automatically and has a good dependency management. Just be aware of

a.) 您需要在 CMake 中正确设置目标依赖项.如果您的构建依赖于另一个工件,则必须等到这些工件被编译(同步点).

a.) You need to setup the target dependencies in CMake correctly. If you get to a point where the build has a dependency to another artifact, it has to wait until those are compiled (synchronization points).

$ time -p cmake -G "Ninja" ..
-- The CXX compiler identification is GNU 4.8.1
...
real 11.06
user 0.00
sys 0.00

$ time -p ninja
...
[202/202] Linking CXX executable CMakeTest.exe
real 40.31
user 0.01
sys 0.01

b.) 链接总是这样一个同步点.所以你可以更多地使用 CMake 的 对象库减少这些,但它会使你的 CMake 代码更丑一些.

b.) Linking is always such a synchronization point. So you can make more use of CMake's Object Libraries to reduce those, but it makes your CMake code a little bit uglier.

$ time -p ninja
...
[102/102] Linking CXX executable CMakeTest.exe
real 27.62
user 0.00
sys 0.04

  • 将不太频繁更改或稳定的代码部分拆分为单独的 CMake 项目,并使用 CMake 的 ExternalProject_Add() 或者 - 如果你例如切换到一些库的二进制交付 - find_library().

    为您的日常工作考虑一组不同的编译器/链接器选项(但前提是您对最终版本构建选项也有一些测试时间/经验).

    Think of a different set of compiler/linker options for your daily work (but only if you also have some test time/experience with the final release build options).

    a.) 跳过优化部分

    b.) 尝试增量链接

    如果您经常更改 CMake 代码本身,请考虑从针对您的机器架构优化的源代码重建 CMake.CMake 官方分发的二进制文件只是在所有可能的 CPU 架构上工作的妥协.

    If you often do changes to the CMake code itself, think about rebuilding CMake from sources optimized for your machine's architecture. CMake's officially distributed binaries are just a compromise to work on every possible CPU architecture.

    当我使用 MinGW64/MSYS 重建 CMake 3.5.2 时,例如

    When I use MinGW64/MSYS to rebuild CMake 3.5.2 with e.g.

    cmake -DCMAKE_BUILD_TYPE:STRING="Release"
          -DCMAKE_CXX_FLAGS:STRING="-march=native -m64 -Ofast -flto"
          -DCMAKE_EXE_LINKER_FLAGS:STRING="-Wl,--allow-multiple-definition"
          -G "MSYS Makefiles" ..
    

    我可以加速第一部分:

    $ time -p [...]/MSYS64/bin/cmake.exe -G "Ninja" ..
    real 6.46
    user 0.03
    sys 0.01
    

  • 如果您的文件 I/O 非常慢并且由于 CMake 使用专用的二进制输出目录,请使用 RAM 磁盘.如果您仍然使用硬盘驱动器,请考虑改用固态硬盘.

  • If your file I/O is very slow and since CMake works with dedicated binary output directories, make use of a RAM disk. If you still use a hard drive, consider switching to a solid state disk.

    根据您的最终输出文件,将 GNU 标准链接器与 Gold Linker 交换.LLVM 项目的 lld 甚至比 Gold Linker 还要快.您必须检查它是否已经支持您平台上所需的功能.

    Depending of your final output file, exchange the GNU standard linker with the Gold Linker. Even faster than Gold Linker is lld from the LLVM project. You have to check whether it supports already the needed features on your platform.

    使用 Clang/c2 而不是 Visual C++ 编译器.有关 Visual C++ 团队提供的 Visual C++ 编译器性能建议,请参阅 https://blogs.msdn.microsoft.com/vcblog/2016/10/26/recommendations-to-speed-c-builds-in-visual-studio/

    Use Clang/c2 instead of Visual C++ compiler. For the Visual C++ compiler performance recommendations are provided from the Visual C++ team, see https://blogs.msdn.microsoft.com/vcblog/2016/10/26/recommendations-to-speed-c-builds-in-visual-studio/

    Increadibuild 可以缩短编译时间.

    参考资料

    这篇关于如何加快启用 CMake 的 C++ 项目的编译时间?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

  • 05-19 06:30