【问题标题】:How to speed up Compile Time of my CMake enabled C++ Project?如何加快启用 CMake 的 C++ 项目的编译时间?
【发布时间】:2016-09-16 14:06:30
【问题描述】:

我最近遇到了几个关于改善启用 CMake 的 C++ 项目的周转时间的特定方面的 SO 问题(例如 "At what level should I distribute my build process?""cmake rebuild_cache for just a subdirectory?"),我想知道是否有更一般的指导来利用特定的可能性CMake 提供。如果可能没有跨平台编译时优化,我主要对基于 Visual Studio 或 GNU 工具链的方法感兴趣。

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

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

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

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

喜欢推荐hereherehere。所以我在这个问题上的重点是第一点。

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

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

为了更具体一点,如果我从here 获取我的 CMake 示例,其中包含 100 个使用 MSYS/GNU 的库,我会得到以下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%。

【问题讨论】:

    标签: performance compilation cmake gnu-make nmake


    【解决方案1】:

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

    1. Ninja 交换GNU make。它更快,自动利用所有可用的 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 的 Object Libraries 来减少这些,但它会让你的 CMake 代码有点难看。

      $ time -p ninja
      ...
      [102/102] Linking CXX executable CMakeTest.exe
      real 27.62
      user 0.00
      sys 0.04
      
    2. 将不太频繁更改或稳定的代码部分拆分为单独的 CMake 项目并使用 CMake 的 ExternalProject_Add() 或 - 如果您使用切换到一些库的二进制交付 - find_library()

    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 标准链接器与 Gold Linker 交换。甚至比 Gold Linker 更快的是来自 LLVM 项目的 lld。您必须检查它是否已经支持您平台上所需的功能。

    7. 使用 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/

    8. Increadibuild 可以提高编译时间。

    参考文献

    【讨论】:

    • 另外,使用 ccache。它使重新编译异常快。
    • 如果您的构建系统正确地进行增量重建,ccache 应该没什么帮助。在编写良好的 cmake 构建正确地进行增量构建时,ccache 实际上会因其开销而减慢您的速度。我过去曾在 ccache 项目上取得过成功,这些项目的构建系统很糟糕,但没有进行增量编译(firefox,几年前)
    【解决方案2】:

    要加快 CMake 配置时间,请参阅:https://github.com/cristianadam/cmake-checks-cache

    LLVM + Clang 获得了约 3 倍的加速。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-14
      • 2021-06-24
      • 2012-12-07
      • 1970-01-01
      相关资源
      最近更新 更多