如何加快启用 CMake 的 C++ 项目的编译时间?
How to speed up Compile Time of my CMake enabled C++ Project?
我最近遇到了几个关于改进启用 CMake 的 C++ 项目的周转时间的特定方面的 SO 问题(例如 "At what level should I distribute my build process?" or "cmake rebuild_cache for just a subdirectory?"),我想知道是否有更通用的指导利用特定的可能性CMake 提供。如果可能没有跨平台编译时优化,我主要对 Visual Studio 或基于 GNU toochain 的方法感兴趣。
而且我已经知道并投资于普遍推荐的领域以加速 C++ 构建:
Change/Optimize/fine-tune 工具链
优化您的代码base/software架构(例如通过减少依赖性并使用定义明确的子项目 - 单元测试)
投资更好的硬件(SSD、CPU、内存)
喜欢推荐 here, here or here。所以我这个问题的重点是第一点。
另外我知道可以在 CMake 的 Wiki 中找到的建议:
前者只处理基础知识(并行制作),后者主要处理如何加速解析 CMake 文件。
只是为了让这个更具体一点,如果我从 here 中使用 100 个库使用 MSYS/GNU 我的 CMake 示例,我得到以下 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 秒,我的目标 - 对于这个公认的非常简单的例子 - 是将它减少到我用标准 settings/tools 得到的大约 10-20%。
以下是我使用 CMake 和 Visual Studio 或 GNU 工具链获得的良好结果:
用 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
将更改频率较低或稳定的代码部分拆分为单独的 CMake 项目并使用 CMake 的 ExternalProject_Add()
or - if you e.g. switch to binary delivery of some libraries - find_library()
.
为您的日常工作考虑一组不同的 compiler/linker 选项(但前提是您还对最终版本构建选项进行了一些测试 time/experience)。
a.) 跳过优化部分
b.) 尝试增量链接
如果您经常更改 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
如果您的文件 I/O 非常慢并且因为 CMake 使用专用二进制输出目录,请使用 RAM 磁盘。如果你还在用硬盘,考虑换成固态硬盘。
根据您的最终输出文件,将 GNU 标准链接器替换为 Gold Linker。比 Gold Linker 更快的是来自 LLVM 项目的 lld。您必须检查它是否已经支持您平台上所需的功能。
使用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 可以缩短编译时间。
参考资料
- Replacing ld with gold - any experience?
要加快 CMake 配置时间,请参阅:https://github.com/cristianadam/cmake-checks-cache
LLVM + Clang 获得了约 3 倍的加速。
我最近遇到了几个关于改进启用 CMake 的 C++ 项目的周转时间的特定方面的 SO 问题(例如 "At what level should I distribute my build process?" or "cmake rebuild_cache for just a subdirectory?"),我想知道是否有更通用的指导利用特定的可能性CMake 提供。如果可能没有跨平台编译时优化,我主要对 Visual Studio 或基于 GNU toochain 的方法感兴趣。
而且我已经知道并投资于普遍推荐的领域以加速 C++ 构建:
Change/Optimize/fine-tune 工具链
优化您的代码base/software架构(例如通过减少依赖性并使用定义明确的子项目 - 单元测试)
投资更好的硬件(SSD、CPU、内存)
喜欢推荐 here, here or here。所以我这个问题的重点是第一点。
另外我知道可以在 CMake 的 Wiki 中找到的建议:
前者只处理基础知识(并行制作),后者主要处理如何加速解析 CMake 文件。
只是为了让这个更具体一点,如果我从 here 中使用 100 个库使用 MSYS/GNU 我的 CMake 示例,我得到以下 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 秒,我的目标 - 对于这个公认的非常简单的例子 - 是将它减少到我用标准 settings/tools 得到的大约 10-20%。
以下是我使用 CMake 和 Visual Studio 或 GNU 工具链获得的良好结果:
用 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
将更改频率较低或稳定的代码部分拆分为单独的 CMake 项目并使用 CMake 的
ExternalProject_Add()
or - if you e.g. switch to binary delivery of some libraries -find_library()
.为您的日常工作考虑一组不同的 compiler/linker 选项(但前提是您还对最终版本构建选项进行了一些测试 time/experience)。
a.) 跳过优化部分
b.) 尝试增量链接
如果您经常更改 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
如果您的文件 I/O 非常慢并且因为 CMake 使用专用二进制输出目录,请使用 RAM 磁盘。如果你还在用硬盘,考虑换成固态硬盘。
根据您的最终输出文件,将 GNU 标准链接器替换为 Gold Linker。比 Gold Linker 更快的是来自 LLVM 项目的 lld。您必须检查它是否已经支持您平台上所需的功能。
使用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 可以缩短编译时间。
参考资料
- Replacing ld with gold - any experience?
要加快 CMake 配置时间,请参阅:https://github.com/cristianadam/cmake-checks-cache
LLVM + Clang 获得了约 3 倍的加速。