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++?
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.
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 ).
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
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
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.
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.
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:
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é:
Rappelez-vous, lors de la détermination de l'efficacité, profilez toujours (d'une manière ou d'une autre).
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.
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.
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
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.
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: