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

时间:2016-05-19 15:17:54

标签: performance compilation cmake gnu-make nmake

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

我已经意识到并投资于通常推荐的领域以加速C ++构建:

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

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

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

  4. 与推荐的hereherehere类似。所以我在这个问题上的重点是第一点。

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

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

    为了使这更具体一点,如果我从here使用MSYS / GNU的100个库获取我的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秒,而我的目标 - 就这个非常简单的例子而言 - 将会降低到标准设置/工具的10-20%。

2 个答案:

答案 0 :(得分:8)

这是我使用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项目。您必须检查它是否已支持您平台上所需的功能。

  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可以延长编译时间。

  9. <强>参考

答案 1 :(得分:0)

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

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