web-dev-qa-db-ja.com

CMake対応のC ++プロジェクトのコンパイル時間を短縮するにはどうすればよいですか?

最近、CMake対応のC++プロジェクトのターンアラウンドタイムを改善する特定の側面に関するいくつかのSO質問に遭遇しました( など) "どのレベルでビルドプロセスを配布する必要がありますか? " または " cmake rebuild_cache forjusta subdirectory? " )、I CMakeが提供する特定の可能性を利用したより一般的なガイダンスがあるかどうか疑問に思っていました。クロスプラットフォームのコンパイル時間の最適化がおそらくない場合、私は主にVisual StudioまたはGNU toochainベースのアプローチに興味があります。

そして、C++ビルドを高速化するために一般的に推奨されている領域をすでに認識しており、それに投資しています。

  1. ツールチェーンの変更/最適化/微調整

  2. コードベース/ソフトウェアアーキテクチャを最適化する(たとえば、依存関係を減らし、明確なサブプロジェクトを使用する-単体テスト)

  3. より優れたハードウェア(SSD、CPU、メモリ)に投資する

推奨 herehere または here など。したがって、この質問で私の焦点は最初の点にあります。

さらに、CMakeのWikiにある推奨事項を知っています。

前者は基本(並列make)を処理するだけで、後者は主にCMakeファイルの解析を高速化する方法を処理します。

これをもう少し具体的にするために、MSYS/GNUを使用して100個のライブラリを here から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%にこれを下げることです。

16
Florian

これは、CMakeとVisual StudioまたはGNUツールチェーンを使用して、良い結果が得られたものです。

  1. Exchange GNU make with Ninja 。より高速で、利用可能なすべての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 と交換します。GoldLinkerよりもさらに高速ですが、LLVMプロジェクトからlldされます。それはあなたのプラットフォームですでに必要な機能をサポートしています。

  7. Visual C++コンパイラの代わりに Clang/c2 を使用します。 Visual C++コンパイラのパフォーマンスに関する推奨事項は、Visual C++チームから提供されています。詳細は https://blogs.msdn.Microsoft.com/vcblog/2016/10/26/recommendations-to-speed-c-builds- in-visual-studio /

  8. Increadibuild はコンパイル時間を短縮できます。

参照

9
Florian

CMake構成時間の高速化については、次を参照してください: https://github.com/cristianadam/cmake-checks-cache

LLVM + Clangは約3倍高速化されました。

0
Cristian Adam