web-dev-qa-db-fra.com

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

Je compile 2 projets C++ dans un buildbot, sur chaque commit. Les deux sont autour de 1000 fichiers, l’un est de 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 20 minutes. Ils ne peuvent pas tirer parti des multiples cœurs, car un projet dépend de l'autre. Au final, une compilation complète des deux projets dans Debug et Release, en 32 et 64 bits prend plus de 2 heures et demie.

les compilations gcc pour un projet prennent 4 minutes. Il peut être parallélisé sur les 4 noyaux et dure environ 1 minute 10 secondes. 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 Visual C++? Ils sont fondamentalement 5 fois plus lents.

Quel est le temps moyen que l'on peut attendre pour compiler 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++?

46
Didier Trosset

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 valeur non-trival const. Cela peut se produire avec des constantes de type std::string ou des GUID. Cela affecte à la fois la compilation et le temps de liaison.

Pour une seule DLL, cela provoquait un ralentissement de 10x. Cela aide si vous les placez dans un fichier d’en-tête précompilé, ou si vous les déclarez simplement dans un en-tête et les initialisez dans un fichier cpp. 

Jetez un coup d'œil dans l'analyseur de virus et assurez-vous d'expérimenter avec les en-têtes précompilés, sans cela, vous ne verrez pas VC++ à son meilleur. 

Ah oui, et assurez-vous que le dossier% TMP% se trouve sur la même partition que celle dans laquelle votre construction est écrite, car VC++ crée des fichiers temporaires et les déplace ultérieurement. 

15
user180326

Les projets qui dépendent les uns des autres n'impliquent pas qu'aucune parallélisation n'est possible. Les systèmes de compilation sont suffisamment intelligents pour comprendre et éviter les dépendances critiques. Sinon, gcc ne pourrait pas utiliser 4 cœurs. 

Alors (en plus d'autres étapes), pourquoi ne pas simplement essayer d'activer le multitraitement dans Visual Studio à l'aide de/MP (Voir http://msdn.Microsoft.com/en-us/library/bb385193.aspx ). 

11
jdisk

Comment construisez-vous les projets Visual Studio? Êtes-vous juste en train de lancer ide (devenv) avec le projet et /build ou avez-vous un fichier Make similaire à ce que je suppose que vous utilisez pour gcc. Je suppose que les deux compilations utilisent un fichier Make similaire, mais je pensais que cela valait la peine d'être vérifié.

Utilisez-vous des en-têtes précompilés pour l'un ou l'autre compilateur? Si vous n'utilisez PAS d'en-têtes précompilés pour les VS, vous voudrez peut-être utiliser ces en-têtes. Personnellement, je vous recommande d’utiliser l’approche #pragma hdrstop plutôt qu’un seul fichier d’entête tout compris, mais si vous n’utilisez PAS actuellement d’en-têtes précompilés et que vous souhaitez essayer un seul fichier d’entête tout inclus inclus de force (en utilisant la ligne de commande du compilateur /FI commutateur) peut être testé rapidement sans aucun changement de code.

J'ai écrit sur /FI et #pragma hdrstop ici: http://www.lenholgate.com/blog/2004/07/fi-stlport-precompiled-headers-warning-level-4-and-pragma-hdrstop.html

6
Len Holgate

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

6
tommyk

Le livre "Conception de logiciels C++ à grande échelle" de John Lakos contient de nombreux conseils pour structurer votre code et votre conception de projets à grande échelle. Y compris de nombreux conseils pour accélérer la compilation. Pas directement lié à Visual C++, mais mérite néanmoins d'être lu.

3
Hollance

J'ai écrit deux articles sur les techniques permettant de réduire le temps de compilation. Parmi ces techniques, un post sur en-tête précompilé et unit est construit qui peut vous aider à améliorer les temps de compilation. Ils sont livrés avec des scripts CMake qui gèrent les techniques de manière transparente.

2
cheind

La vérification de la dépendance pose peut-être un problème, à moins que vous ne forçiez une reconstruction complète.

Vous pouvez créer des bibliothèques statiques. Mettez du 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 des fichiers source

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

Avez-vous déterminé:

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

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

1
Thomas Matthews

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.

De plus, ce que vous décrivez semble horriblement lent - vous n’avez pas l’impression d’utiliser des en-têtes précompilés dans VC++ ni de les utiliser incorrectement - ils sont spécifiquement conçus pour améliorer le temps de compilation.

1
sharptooth

Je ne sais pas si cela reste un problème ni quelle amélioration vous avez eu dans le calendrier, mais s'il est toujours possible que msbuild ne sache pas comment orchestrer simultanément dans un projet (chaque cpp doit pouvoir être construit séparément à moins que vous ne possédiez des codes - Il est préférable de déplacer les codgènes vers un projet séparé). Vous devez télécharger le kit de développement de pilote ou .NET SSCLI , car ils ont tous les deux nmake, une version bien connue pour bien faire la parallèle. SSCLI avait déjà la configuration de construction, ne vous en souvenez pas si DDK a quelques exemples de construction, vous devez tout recommencer.

Egalement un peu oldish article sur MSBuild la parallélisation ne va pas dans les détails mais mentionne quelques différences entre msbuild et msbuild + sln. Si le seul problème concerne/MP vs./Gm, vous devrez peut-être créer un petit script ou un fichier C # exe pour modifier les fichiers .proj en vue de la création d'un laboratoire. Vous pouvez également utiliser le remplacement de ligne de commande explicite dans les projets et choisir cette option dans une variable env.

0
ZXX

Compilez et liez un fichier cpp à la fois , même lorsque les modifications apportées à l'en-tête de fichier affectent plusieurs fichiers cpp. Ceci peut être réalisé avec Visual Studio Macro:

Dim WithEvents myTimer As Timers.Timer

Sub CompileAndLinkCurrentCppFile()
    DTE.ExecuteCommand("Build.Compile")
    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
0
AareP

Vous construisez sur la même machine? Utilisez-vous le même système d'exploitation? J'ai constaté des différences de vitesse de l'ordre de 3-10x lorsque l'on compare GCC dans Cygwin et GCC dans une machine VirtualBox exécutée dans l'hébergement Windows Cygwin.

0
e8johan

Il semble très étrange qu'il y ait une telle différence ... mais il n'y a aucune raison pour que vous ne puissiez pas non plus profiter des multicœurs sur Visual!

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

Cependant cela ne va pas le couper. 150 minutes contre 10 minutes est un énorme écart. D'après mon expérience personnelle, il existe 2 facteurs principaux dans la réduction du temps de compilation:

  • avoir tous les fichiers utilisés sur un disque local (en utilisant la réplication à partir de fichiers distants si nécessaire) et tous les fichiers créés localement aussi (.o .so)
  • utilisez tous les noyaux à votre disposition, et si vous le pouvez, allez même sur Multi Machines (distcc etc ...)
0
Matthieu M.