performance - ¿Cómo acelerar el tiempo de compilación de mi proyecto C++ habilitado para CMake?
compilation gnu-make (2)
Recientemente me encontré con varias preguntas SO sobre aspectos específicos de la mejora del tiempo de respuesta de los proyectos C ++ habilitados para CMake (como "¿A qué nivel debo distribuir mi proceso de compilación?" O "cmake rebuild_cache por solo un subdirectorio?" ), Estaba preguntándose si hay una guía más general que utilice las posibilidades específicas que CMake ofrece. Si probablemente no hay optimización de tiempo de compilación multiplataforma, estoy principalmente interesado en los enfoques basados en Visual Studio o GNU también en cadena.
Y ya conozco e invierto en las áreas generalmente recomendadas para acelerar las compilaciones de C ++:
-
Cambiar / Optimizar / ajustar la cadena de herramientas
-
Optimice su base de código / arquitectura de software (por ejemplo, reduciendo las dependencias y utilice subproyectos bien definidos - pruebas unitarias)
-
Invierta en un mejor hardware (SSD, CPU, memoria)
como recomendado here , here o here . Entonces mi enfoque en esta pregunta está en el primer punto.
Además, conozco las recomendaciones que se encuentran en el Wiki de CMake:
El primero solo maneja los conceptos básicos (creación paralela), el segundo maneja principalmente cómo acelerar el análisis de archivos CMake.
Solo para hacer esto un poco más concreto, si tomo mi ejemplo CMake de
here
con 100 bibliotecas que usan MSYS / GNU, obtengo los siguientes resultados de medición de
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
Por lo tanto, tengo un total de ~ 140 segundos y mi objetivo, para este ejemplo ciertamente simple, sería reducir esto a aproximadamente el 10-20% de lo que obtengo con las configuraciones / herramientas estándar.
Esto es lo que obtuve buenos resultados con el uso de cadenas de herramientas CMake y Visual Studio o GNU:
-
Intercambia GNU make con Ninja . Es más rápido, utiliza automáticamente todos los núcleos de CPU disponibles y tiene una buena gestión de dependencias. Solo ten en cuenta
a.) Debe configurar las dependencias de destino en CMake correctamente. Si llega a un punto en el que la compilación depende de otro artefacto, debe esperar hasta que se compilen (puntos de sincronización).
$ 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 vinculación es siempre un punto de sincronización. Por lo tanto, puede hacer un mayor uso de las bibliotecas de objetos de CMake para reducirlas, pero hace que su código de CMake sea un poco más feo.
$ time -p ninja ... [102/102] Linking CXX executable CMakeTest.exe real 27.62 user 0.00 sys 0.04
-
Divida partes de código estables o que cambien con menos frecuencia en proyectos CMake separados y use
ExternalProject_Add()
CMake o, si, por ejemplo, cambia a la entrega binaria de algunas bibliotecas,find_library()
. -
Piense en un conjunto diferente de opciones de compilador / enlazador para su trabajo diario (pero solo si también tiene algo de tiempo de prueba / experiencia con las opciones de compilación de la versión final).
a.) Omita las partes de optimización
b.) Pruebe la vinculación incremental
-
Si a menudo realiza cambios en el propio código CMake, piense en reconstruir CMake a partir de fuentes optimizadas para la arquitectura de su máquina. Los binarios distribuidos oficialmente de CMake son solo un compromiso para trabajar en todas las arquitecturas de CPU posibles.
Cuando uso MinGW64 / MSYS para reconstruir CMake 3.5.2 con, por ejemplo,
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" ..
Puedo acelerar la primera parte:
$ time -p [...]/MSYS64/bin/cmake.exe -G "Ninja" .. real 6.46 user 0.03 sys 0.01
-
Si la E / S de su archivo es muy lenta y dado que CMake funciona con directorios de salida binarios dedicados, utilice un disco RAM. Si todavía usa un disco duro, considere cambiar a un disco de estado sólido.
-
Dependiendo de su archivo de salida final, intercambie el enlazador estándar GNU con el Gold Linker . Incluso más rápido que Gold Linker es lld del proyecto LLVM. Debe verificar si ya es compatible con las características necesarias en su plataforma.
-
Use Clang/c2 lugar del compilador de Visual C ++. Para obtener las recomendaciones de rendimiento del compilador de Visual C ++ del equipo de Visual C ++, consulte https://blogs.msdn.microsoft.com/vcblog/2016/10/26/recommendations-to-speed-c-builds-in-visual-studio/
-
Increadibuild puede aumentar el tiempo de compilación.
Referencias
Para acelerar el tiempo de configuración de CMake, consulte: https://github.com/cristianadam/cmake-checks-cache
LLVM + Clang tiene una aceleración ~ 3x.