Comment améliorer les temps de compilation de Visual C ++?

Je comstack 2 projets C ++ dans un buildbot, à chaque validation. Les deux sont environ 1000 fichiers, l’un est 100 kloc, l’autre 170 kloc. Les temps de compilation sont très différents de gcc (4.4) à Visual C ++ (2008).

Les compilations Visual C ++ pour un projet prennent dans les 20 minutes. Ils ne peuvent pas profiter des multiples cœurs car un projet dépend de l’autre. Au final, une compilation complète des deux projets dans Debug and Release, en 32 et 64 bits, prend plus de deux heures et demie.

Les compilations gcc pour un projet prennent dans les 4 minutes. Il peut être parallélisé sur les 4 cœurs et prend environ 1 min 10 s. Les 8 versions pour 4 versions (Debug / Release, 32/64 bits) des 2 projets sont compilées en moins de 10 minutes.

Que se passe-t-il avec les temps de compilation de Visual C ++? Ils sont fondamentalement 5 fois plus lents.

Quel est le délai moyen de compilation d’un kloc C ++? Les miens sont 7 s / kloc avec vc ++ et 1,4 s / kloc avec gcc.

Peut-on faire quelque chose pour accélérer les temps de compilation sur Visual C ++?

Une chose qui ralentit le compilateur VC ++ est si vous avez un fichier d’en-tête qui initialise des instances concrètes de types de valeurs const non-sortingval. Vous pouvez voir cela se produire avec des constantes de type std::ssortingng ou GUID. Cela affecte à la fois la compilation et le temps de liaison.

Pour une seule DLL, cela a causé un ralentissement de 10 fois. Cela aide si vous les placez dans un fichier d’en-tête précompilé, ou simplement les déclarer dans un en-tête et les initialiser dans un fichier cpp.

Jetez un coup d’œil au scanner de virus et assurez-vous d’expérimenter avec des en-têtes précompilés. Sans lui, vous ne verrez pas le meilleur de VC ++.

Oh oui, et assurez-vous que le dossier% TMP% est sur la même partition que celle où votre build est écrite, car VC ++ crée des fichiers temporaires et les déplace plus tard.

Les projets dépendant les uns des autres n’impliquent pas qu’aucune parallélisation n’est possible. Les systèmes de construction sont suffisamment intelligents pour déterminer et éviter les dépendances critiques, sinon gcc ne pourrait pas utiliser 4 cœurs.

Donc, en plus des autres étapes, pourquoi ne pas essayer d’activer le multitraitement dans Visual Studio avec / MP (voir http://msdn.microsoft.com/en-us/library/bb385193.aspx ).

Ce n’est pas la réponse directe à la question, mais dans mon entreprise, nous utilisons IncrediBuild pour la compilation dissortingbuée. Cela accélère vraiment le processus de compilation. http://incredibuild.com/visual_studio.htm

Comment construisez-vous les projets Visual Studio? Est-ce que vous utilisez simplement le ide (devenv) avec le projet et /build ou avez-vous un fichier makefile similaire à celui que vous utilisez pour gcc? Je suppose que les deux versions utilisent un fichier makefile similaire, mais je pensais que cela valait la peine de le vérifier.

Utilisez-vous des en-têtes précompilés pour l’un des compilateurs? Si vous n’utilisez PAS d’en-têtes précompilés pour VS, vous souhaiterez peut-être les utiliser. Personnellement, je vous recommande d’utiliser l’approche #pragma hdrstop plutôt qu’un seul fichier d’en-tête inclusif, mais si vous n’utilisez PAS d’en-têtes précompilés et que vous voulez essayer un fichier d’en-tête inclusif inclus commutateur de ligne de commande du compilateur) peut être testé rapidement sans aucune modification de code.

J’ai écrit à propos des deux /FI et #pragma hdrstop ici: http://www.lenholgate.com/blog/2004/07/fi-stlport-precomstackd-headers-warning-level-4-and-pragma-hdrstop.html

Le livre “Conception de logiciels C ++ à grande échelle” de John Lakos offre de nombreux conseils sur la structuration de votre code et la conception de projets à grande échelle. Y compris de nombreux conseils pour accélérer la compilation. Pas directement lié à Visual C ++, mais cela vaut la peine de le lire quand même.

J’ai écrit deux articles sur les techniques qui réduisent le temps de compilation. Parmi ces techniques, un article sur l’en- tête et l’ unité précompilés est créé pour vous aider à améliorer les temps de compilation. Ils sont livrés avec des scripts CMake qui traitent les techniques de manière transparente.

Tout d’abord, dans la plupart des cas, vous pouvez créer des configurations de débogage et de publication du même projet en parallèle.

En outre, ce que vous décrivez semble terriblement lent – on dirait que vous n’utilisez pas les en-têtes précompilés dans VC ++ ou que vous ne les utilisez pas correctement – ils sont spécifiquement destinés à améliorer le temps de compilation.

Il y a peut-être un problème avec la vérification des dépendances, à moins que vous ne forciez une reconstruction complète.

Vous pourriez créer des bibliothèques statiques. Mettez le code qui change rarement dans les bibliothèques.

Les parties les plus lentes de la construction d’un programme:

  1. Ouverture et fermeture de fichiers.
  2. Analyse et traduction de fichiers source.

En général, les phases de création de liens et d’exécutables sont les plus rapides.

Avez-vous déterminé:

  1. quelles sont les phases les plus lentes?
  2. Quels fichiers sont les plus lents à comstackr?

Rappelez-vous, lors de la détermination de l’efficacité, toujours profiler (d’une manière ou d’une autre).

Est-ce que vous construisez sur la même machine? Utilisez-vous le même système d’exploitation? J’ai vu des différences de vitesse dans la région de 3 à 10x en comparant GCC dans Cygwin et GCC dans une machine VirtualBox exécutée dans Windows hébergeant Cygwin.

Il semble très étrange qu’il y ait une telle différence … mais il n’y a pas non plus de raison pour que vous ne puissiez pas profiter des multicores sur Visual!

Fondamentalement, vous disposez de 4 modes de compilation: (Debug / Release) x (32bits / 64bits), chacun étant totalement indépendant l’un de l’autre, vous pouvez parfaitement exécuter le 4 en parallèle, en tirant pleinement parti des 4 cœurs disponibles. Ou essayez simplement l’approche MultiProcessor sur Visual Studio.

Cependant, cela ne va pas le couper. 150 minutes contre 10 minutes est un énorme écart. De mon expérience personnelle, il y a deux facteurs majeurs dans la réduction du temps de compilation:

  • avoir tous les fichiers utilisés sur un disque local (en utilisant la réplication de ceux distants si nécessaire) et tous les fichiers créés localement aussi (.o .so)
  • utiliser tous les cœurs à votre disposition, et si vous le pouvez, même aller sur les Multi Machines (distcc etc …)

Comstackz et liez un fichier cpp à la fois , même lorsque les modifications d’en-tête-fichier affectent plusieurs fichiers cpp. Cela peut être accompli avec la macro visuelle de studio:

 Dim WithEvents myTimer As Timers.Timer Sub ComstackAndLinkCurrentCppFile() DTE.ExecuteCommand("Build.Comstack") myTimer = New Timers.Timer myTimer.Interval = 0.05 myTimer.Start() End Sub Sub myTimer_Elapsed(ByVal ee As Object, ByVal dd As Timers.ElapsedEventArgs) Handles myTimer.Elapsed If DTE.Solution.SolutionBuild.BuildState <> vsBuildState.vsBuildStateInProgress And DTE.Solution.SolutionBuild.LastBuildInfo <> 1 Then myTimer.Stop() DTE.ExecuteCommand("Build.Link") End If End Sub 

Je ne sais pas si c’est toujours un problème et combien d’améliorations vous avez dans le menatime, mais s’il rest que msbuild ne sait pas orchestrer en même temps dans un projet (chaque cpp devrait pouvoir être construit séparément à moins que vous n’ayez un code) – Les codesgens sont mieux déplacés vers un projet séparé. Vous devez télécharger le kit de développement de pilotes ou .NET SSCLI car ils ont tous deux une configuration nmake connue pour bien faire les choses. SSCLI avait déjà la configuration de build build, ne vous souvenez pas si DDK a des exemples de build dont vous avez besoin pour partir de zéro.

Un article un peu ancien sur la parallélisation MSBuild n’entre pas dans les détails, mais mentionne des différences entre msbuild et msbuild + sln. Si le / MP vs / Gm était le seul problème alors vous devrez peut-être faire un petit script ou C # exe pour éditer des fichiers .proj pour la construction en laboratoire. Ou utilisez le remplacement explicite de la ligne de commande cmd dans les projets et utilisez cette option depuis une variable env.