如何加快启用 CMake 的 C++ 项目的编译时间?

2024-01-14

我最近遇到了几个关于改善支持 CMake 的 C++ 项目的周转时间的特定方面的问题(例如“我应该在什么级别上分发我的构建过程?” https://stackoverflow.com/questions/37276312/at-what-level-should-i-distribute-my-build-process or “cmake重建_缓存just子目录?” https://stackoverflow.com/questions/35436945/cmake-rebuild-cache-for-just-a-subdirectory),我想知道是否有利用 CMake 提供的特定可能性的更一般的指导。如果可能没有跨平台编译时优化,我主要对基于 Visual Studio 或 GNU 工具链的方法感兴趣。

我已经了解并投资了一般推荐的领域来加速 C++ 构建:

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

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

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

喜欢推荐的here https://stackoverflow.com/questions/373142/what-techniques-can-be-used-to-speed-up-c-compilation-times, here https://stackoverflow.com/questions/3396958/how-to-speed-up-g-compile-time-when-using-a-lot-of-templates or here https://stackoverflow.com/questions/6321679/effective-c-35-minimize-compilation-dependencies-between-files-is-it-still。所以我这个问题的重点是第一点。

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

  • CMake:使用所有核心进行构建 https://blog.kitware.com/cmake-building-with-all-your-cores/
  • CMake 性能技巧 https://gitlab.kitware.com/cmake/community/-/wikis/doc/cmake/Performance-Tips

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

只是为了让这个更具体一点,如果我以我的 CMake 为例here https://stackoverflow.com/questions/35436945/cmake-rebuild-cache-for-just-a-subdirectory/35826669#35826669使用 MSYS/GNU 的 100 个库我得到以下结果time测量结果:

$ 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% 左右。


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

  1. 交换 GNU make 与Ninja https://ninja-build.org/。它速度更快,自动利用所有可用的 CPU 内核,并且具有良好的依赖性管理。请注意

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

    $ 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的对象库 https://cmake.org/cmake/help/latest/command/add_library.html#object-libraries来减少这些,但这会让你的 CMake 代码变得有点难看。

    $ time -p ninja
    ...
    [102/102] Linking CXX executable CMakeTest.exe
    real 27.62
    user 0.00
    sys 0.04
    
  2. 将不经常更改或稳定的代码部分拆分为单独的 CMake 项目并使用 CMakeExternalProject_Add() https://cmake.org/cmake/help/latest/module/ExternalProject.html或者 - 如果你例如切换到一些库的二进制交付 -find_library() https://cmake.org/cmake/help/latest/command/find_library.html.

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

    a.) 跳过优化部分

    b.) 尝试增量链接

  4. 如果您经常对 CMake 代码本身进行更改,请考虑从针对您的计算机架构优化的源重建 CMake。 CMake 的官方分发的二进制文件只是在每种可能的 CPU 架构上工作的折衷方案。

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

    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
    
  5. 如果您的文件 I/O 非常慢,并且由于 CMake 使用专用的二进制输出目录,请使用 RAM 磁盘。如果您仍然使用硬盘,请考虑改用固态硬盘。

  6. 根据您的最终输出文件,将 GNU 标准链接器与黄金链接者 https://en.wikipedia.org/wiki/Gold_(linker)。 LLVM 项目的 lld 甚至比 Gold Linker 还要快。您必须检查它是否已经支持您平台上所需的功能。

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

  8. 英科迪建筑 https://www.incredibuild.com/可以增加编译时间。

参考

  • CMake:如何设置源、库和 CMakeLists.txt 依赖项? https://stackoverflow.com/questions/31512485/cmake-how-to-setup-source-library-and-cmakelists-txt-dependencies
  • 用黄金代替 ld - 有什么经验吗? https://stackoverflow.com/questions/3476093/replacing-ld-with-gold-any-experience
  • lld 链接器是 ld 和 gold 的直接替代品吗? https://stackoverflow.com/questions/29361801/is-the-lld-linker-a-drop-in-replacement-for-ld-and-gold
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何加快启用 CMake 的 C++ 项目的编译时间? 的相关文章

随机推荐