web-dev-qa-db-fra.com

Comment accélérer le temps de compilation de mon projet C++ activé par CMake?

J'ai rencontré plusieurs SO questions sur des aspects spécifiques de l'amélioration du délai d'exécution des projets C++ activés par CMake (comme "À quel niveau dois-je distribuer mon processus de construction?" } Ou "cmake rebuild_cache pour juste un sous-répertoire?" ), je me demandais s'il existait un guide plus général utilisant les possibilités spécifiques offertes par CMake. S'il n'y a probablement pas d'optimisation multi-plateforme du temps de compilation, je m'intéresse principalement aux approches basées sur Visual Studio ou GNU toochain.

Et je connais déjà et investit dans les domaines généralement recommandés pour accélérer les versions C++:

  1. Changer/Optimiser/affiner la chaîne d'outils

  2. Optimisez votre architecture de base de code/logiciel (par exemple en réduisant les dépendances et en utilisant des sous-projets bien définis - tests unitaires)

  3. Investissez dans un meilleur matériel (SSD, CPU, mémoire)

comme recommandé ici _, ici ou ici . Donc, dans cette question, je me concentre sur le premier point.

De plus, je connais les recommandations figurant dans le wiki de CMake:

Le premier ne traite que les bases (fabrication parallèle), le dernier traite principalement de la manière d'accélérer l'analyse des fichiers CMake.

Pour rendre cela un peu plus concret, si je prends mon exemple CMake de ici avec 100 bibliothèques utilisant MSYS/GNU, j'ai obtenu les résultats de mesure time suivants:

$ 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

Donc, j'ai un total d'environ 140 secondes et mon objectif - pour cet exemple certes très simple - serait de réduire ce nombre à environ 10 à 20% de ce que j'obtiens avec les paramètres/outils standard.

12
Florian

Voici ce que j'ai obtenu avec CMake et Visual Studio ou GNU toolchains: 

  1. Exchange GNU make avec Ninja . Il est plus rapide, utilise automatiquement tous les cœurs de processeur disponibles et offre une bonne gestion des dépendances. Juste être conscient de

    a.) Vous devez configurer correctement les dépendances cibles dans CMake. Si vous parvenez à un point où la construction est dépendante d'un autre artefact, il doit attendre que ceux-ci soient compilés (points de synchronisation).

    $ 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.) La liaison est toujours un tel point de synchronisation. Vous pouvez donc utiliser davantage les bibliothèques d'objets de CMake pour les réduire, mais cela rend votre code CMake un peu plus laid.

    $ time -p ninja
    ...
    [102/102] Linking CXX executable CMakeTest.exe
    real 27.62
    user 0.00
    sys 0.04
    
  2. Divisez les parties de code moins fréquemment modifiées ou stables dans des projets CMake distincts et utilisez ExternalProject_Add() de CMake - ou - si vous par ex. passer à la livraison binaire de certaines bibliothèques - find_library() .

  3. Pensez à un ensemble différent d'options de compilateur/éditeur de liens pour votre travail quotidien (mais uniquement si vous disposez également d'une certaine expérience/expérience de test avec les options de construction de la version finale).

    a.) Passer les pièces d'optimisation

    b.) Essayez la liaison incrémentielle

  4. Si vous modifiez souvent le code CMake lui-même, pensez à reconstruire CMake à partir de sources optimisées pour l'architecture de votre machine. Les binaires officiellement distribués de CMake ne sont qu'un compromis pour travailler sur toutes les architectures de CPU possibles.

    Lorsque j'utilise MinGW64/MSYS pour reconstruire CMake 3.5.2 avec par exemple.

    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" .. 
    

    Je peux accélérer la première partie:

    $ time -p [...]/MSYS64/bin/cmake.exe -G "Ninja" ..
    real 6.46
    user 0.03
    sys 0.01
    
  5. Si votre E/S de fichier est très lente et que CMake fonctionne avec des répertoires de sortie binaires dédiés, utilisez un disque RAM. Si vous utilisez toujours un disque dur, envisagez de passer à un disque SSD.

  6. En fonction de votre fichier de sortie final, remplacez l'éditeur de liens GNU standard par Gold Linker . Même plus rapidement que Gold Linker est lld du projet LLVM. Vous devez vérifier s'il prend déjà en charge les fonctionnalités nécessaires sur votre plate-forme.

  7. Utilisez Clang/c2 au lieu du compilateur Visual C++. Les recommandations de performances du compilateur Visual C++ sont fournies à partir de l'équipe Visual C++, voir https://blogs.msdn.Microsoft.com/vcblog/2016/10/26/recommendations-to-speed-c-builds-in -Visual Studio/

  8. Increadibuild peut augmenter le temps de compilation.

Références

8
Florian

Pour accélérer la configuration de CMake, voir: https://github.com/cristianadam/cmake-checks-cache

LLVM + Clang a obtenu une accélération d'environ 3 fois.

0
Cristian Adam