web-dev-qa-db-fra.com

Comment faire en sorte que Windows soit aussi rapide que Linux pour compiler C++?

Je sais que ce n’est pas vraiment une question de programmation, mais elle est pertinente.

Je travaille sur un assez grand projet multiplateforme . Sous Windows, j'utilise VC++ 2008. Sous Linux, j'utilise gcc. Il y a environ 40k fichiers dans le projet. Windows est 10 à 40 fois plus lent que Linux à compiler et à lier le même projet. Comment puis-je résoudre ce problème?

Une seule modification incrémentielle construire 20 secondes sur Linux et> 3 minutes sur Windows. Pourquoi? Je peux même installer l’éditeur de liens «gold» sous Linux et obtenir ce temps à 7 secondes.

De même, git est 10x à 40x plus rapide sous Linux que Windows. 

Dans le cas de git, il est possible que git n'utilise pas Windows de manière optimale, mais VC++? On pourrait penser que Microsoft voudrait rendre ses propres développeurs aussi productifs que possible et une compilation plus rapide contribuerait grandement à cela. Peut-être qu'ils essaient d'encourager les développeurs à utiliser C #?

En guise de test simple, recherchez un dossier contenant de nombreux sous-dossiers et effectuez une opération simple.

dir /s > c:\list.txt

sous Windows. Faites-le deux fois et chronométrez la deuxième exécution pour qu'elle soit exécutée à partir du cache. Copiez les fichiers sous Linux et effectuez l'équivalent de 2 exécutions et la seconde exécution.

ls -R > /tmp/list.txt

J'ai 2 postes de travail avec exactement les mêmes spécifications. HP Z600 avec 12gig de RAM, 8 cœurs à 3.0ghz. Sur un dossier contenant environ 400 000 fichiers, Windows prend 40 secondes, Linux prend <1 seconde.

Existe-t-il un paramètre de registre que je peux définir pour accélérer Windows? Ce qui donne?


Quelques liens légèrement pertinents, pertinents pour la compilation des temps, pas nécessairement en entrée/sortie.

134
gman

À moins qu'un hacker hardcore des systèmes Windows ne se présente, vous n'obtiendrez que des commentaires partisans (ce que je ne ferai pas) et des spéculations (ce que je vais essayer d'essayer).

  1. Système de fichiers - Vous devriez essayer les mêmes opérations (y compris la dir) sur le même système de fichiers. Je suis tombé sur this qui teste quelques systèmes de fichiers pour divers paramètres.

  2. Caching. Une fois, j’ai essayé d’exécuter une compilation sous Linux sur un disque RAM et j’ai trouvé que c’était plus lent que de l’exécuter sur disque, grâce à la façon dont le noyau s’occupait de la mise en cache. C’est un argument de vente solide pour Linux et peut-être la raison pour laquelle les performances sont si différentes. 

  3. Mauvaises spécifications de dépendance sous Windows. Peut-être que les spécifications de dépendance au chrome pour Windows ne sont pas aussi correctes que pour Linux. Cela peut entraîner des compilations inutiles lorsque vous effectuez une petite modification. Vous pourrez peut-être valider cela à l'aide de la même chaîne d'outils du compilateur sous Windows.

32
Noufal Ibrahim

Quelques idées:

  1. Désactiver les noms 8.3. Cela peut être un facteur important sur les lecteurs avec un grand nombre de fichiers et un nombre relativement petit de dossiers: fsutil behavior set disable8dot3 1
  2. Utilisez plus de dossiers. D'après mon expérience, NTFS commence à ralentir avec plus de 1000 fichiers par dossier.
  3. Activer les constructions parallèles avec MSBuild; ajoutez simplement le commutateur "/ m", et il lancera automatiquement une copie de MSBuild par cœur de processeur.
  4. Mettez vos fichiers sur un SSD - aide énormément pour les E/S aléatoires.
  5. Si votre taille de fichier moyenne est beaucoup plus grande que 4 Ko, envisagez de reconstruire le système de fichiers avec une taille de cluster plus grande qui correspond à peu près à votre taille de fichier moyenne.
  6. Assurez-vous que les fichiers ont été défragmentés. Les fichiers fragmentés génèrent beaucoup de recherches sur le disque, ce qui peut vous coûter un facteur de production supérieur à 40. Utilisez l'utilitaire "contig" de sysinternals ou le défragmenteur Windows intégré.
  7. Si la taille moyenne de votre fichier est petite et que la partition sur laquelle vous vous trouvez est relativement pleine, il est possible que vous utilisiez une MFT fragmentée, ce qui nuit aux performances. De plus, les fichiers inférieurs à 1K sont stockés directement dans la MFT. L'utilitaire "contig" mentionné ci-dessus peut vous aider ou vous devrez peut-être augmenter la taille de la MFT. La commande suivante doublera le volume, à 25% du volume: fsutil behavior set mftzone 2 Modifiez le dernier nombre en 3 ou 4 pour augmenter la taille par incréments supplémentaires de 12,5%. Après avoir exécuté la commande, redémarrez, puis créez le système de fichiers.
  8. Désactiver l'heure du dernier accès: fsutil behavior set disablelastaccess 1
  9. Désactiver le service d'indexation
  10. Désactivez vos logiciels anti-virus et anti-spyware, ou du moins définissez les dossiers appropriés de manière à ce qu’ils soient ignorés.
  11. Placez vos fichiers sur un lecteur physique différent du système d'exploitation et du fichier d'échange. L'utilisation d'un lecteur physique distinct permet à Windows d'utiliser des E/S parallèles sur les deux lecteurs.
  12. Regardez les drapeaux de votre compilateur. Le compilateur Windows C++ a une tonne d'options; assurez-vous que vous utilisez uniquement ceux dont vous avez réellement besoin.
  13. Essayez d'augmenter la quantité de mémoire utilisée par le système d'exploitation pour les mémoires tampons de pool paginé (assurez-vous que vous avez suffisamment RAM en premier): fsutil behavior set memoryusage 2
  14. Consultez le journal des erreurs Windows pour vous assurer que vous ne rencontrez pas d'erreurs de disque occasionnelles.
  15. Examinez les compteurs de performance liés aux disques physiques pour voir l’occupation de vos disques. Des files d'attente trop longues ou de longues durées par transfert sont de mauvais signes.
  16. Le premier 30% de partitions de disque est beaucoup plus rapide que le reste du disque en termes de temps de transfert brut. Les partitions plus étroites aident également à minimiser les temps de recherche.
  17. Utilisez-vous le RAID? Si tel est le cas, vous devrez peut-être optimiser votre choix de type de RAID (RAID-5 est mauvais pour les opérations nécessitant beaucoup d'écriture, telles que la compilation).
  18. Désactiver tous les services dont vous n'avez pas besoin
  19. Défragmenter les dossiers: copier tous les fichiers sur un autre lecteur (uniquement les fichiers), supprimer les fichiers d'origine, copier tous les dossiers sur un autre lecteur (uniquement les dossiers vides), puis supprimer les dossiers d'origine, défragmenter le lecteur d'origine, copier la structure de dossiers en premier , puis copiez les fichiers. Lorsque Windows crée des dossiers volumineux, un fichier à la fois, ceux-ci finissent par être fragmentés et lents. ("contig" devrait aider ici aussi)
  20. Si vous êtes lié aux E/S et que vous avez des cycles de processeur à épargner, essayez d'activer la compression de disque. Il peut fournir des accélérations significatives pour les fichiers hautement compressibles (comme le code source), avec un coût en CPU.
25
RickNZ

NTFS enregistre l'heure d'accès aux fichiers à chaque fois. Vous pouvez essayer de le désactiver: "Comportement fsutil défini sur disablelastaccess 1" (Redémarrage)

23
Agent_L

Le problème avec Visual C++ est, à ce que je sache, qu’il n’est pas prioritaire pour l’équipe du compilateur d’optimiser ce scénario. Leur solution est d’utiliser leur en-tête précompilé. C'est ce que des projets spécifiques à Windows ont fait. Ce n'est pas portable, mais ça marche. 

En outre, sur Windows, vous disposez généralement d’analyseurs de virus, ainsi que d’outils de restauration du système et de recherche qui peuvent ruiner complètement vos temps de génération s’ils surveillent votre dossier buid à votre place. Windows 7 resouce Monitor peut vous aider à le repérer . J'ai une réponse ici avec quelques astuces supplémentaires pour optimiser les temps de construction de vc ++ si vous êtes vraiment intéressé.

20
user180326

J'ai personnellement découvert que l'exécution d'une machine virtuelle Windows sur Linux permettait de supprimer une bonne partie de la lenteur de IO dans Windows, probablement parce que la machine virtuelle Linux faisait beaucoup de mise en cache, contrairement à Windows.

Ce faisant, j’ai pu accélérer les temps de compilation d’un grand projet C++ (250Kloc) sur lequel je travaillais, de 15 minutes à 6 minutes environ.

16
bfrog

La difficulté réside dans le fait que le C++ a tendance à s’étendre et à faciliter le processus de compilation sur de nombreux petits fichiers individuels. C'est une chose à laquelle Linux est bon et Windows ne l'est pas. Si vous voulez créer un compilateur C++ très rapide pour Windows, essayez de tout conserver dans RAM et de toucher le moins possible au système de fichiers.

C'est également ainsi que vous créerez une chaîne de compilation Linux C++ plus rapide, mais cela est moins important sous Linux car le système de fichiers effectue déjà beaucoup de ce réglage pour vous.

La raison en est due à la culture Unix: Historiquement, les performances du système de fichiers étaient beaucoup plus prioritaires dans le monde Unix que dans Windows. Cela ne veut pas dire que cela n’a pas été une priorité dans Windows, mais seulement sous Unix, il a été prioritaire.

  1. Accès au code source.

    Vous ne pouvez pas changer ce que vous ne pouvez pas contrôler. Le manque d'accès au code source Windows NTFS signifie que la plupart des efforts déployés pour améliorer les performances ont consisté en des améliorations matérielles. En d’autres termes, si les performances sont lentes, vous résolvez le problème en améliorant le matériel: le bus, le support de stockage, etc. Vous ne pouvez faire beaucoup plus si vous devez contourner le problème, pas le résoudre.

    L’accès au code source Unix (même avant l’open source) était plus répandu. Par conséquent, si vous souhaitez améliorer les performances, vous devez l’adresser d'abord au logiciel (moins cher et plus facile) et au matériel.

    En conséquence, de nombreuses personnes dans le monde ont obtenu leur doctorat en étudiant le système de fichiers Unix et en trouvant de nouveaux moyens d’améliorer leurs performances.

  2. Unix tend vers de nombreux petits fichiers; Windows tend vers quelques gros (ou un seul) gros fichier.

    Les applications Unix ont tendance à traiter de nombreux petits fichiers. Pensez à un environnement de développement logiciel: de nombreux petits fichiers source, chacun ayant son propre objectif. La dernière étape (la création de liens) crée un seul gros fichier, mais il s’agit d’un petit pourcentage.

    En conséquence, Unix a des appels système hautement optimisés pour l'ouverture et la fermeture de fichiers, l'analyse de répertoires, etc. L'historique des travaux de recherche Unix couvre des décennies d'optimisation du système de fichiers qui ont beaucoup réfléchi à l'amélioration de l'accès aux répertoires (recherches et analyses des répertoires complets), à l'ouverture initiale des fichiers, etc.

    Les applications Windows ont tendance à ouvrir un gros fichier, à le maintenir ouvert longtemps, à le fermer une fois terminé. Pensez à MS-Word. msword.exe (ou autre) ouvre le fichier une fois et l'ajoute pendant des heures, met à jour les blocs internes, etc. L'optimisation de l'ouverture du fichier serait une perte de temps.

    L’analyse comparative et l’optimisation de Windows ont porté sur la rapidité avec laquelle on peut lire ou écrire de longs fichiers. C'est ce qui est optimisé.

    Malheureusement, le développement de logiciels a évolué vers la première situation. Heck, le meilleur système de traitement de texte pour Unix (TeX/LaTeX) vous encourage à placer chaque chapitre dans un fichier différent et à les inclure tous ensemble.

  3. Unix est axé sur la haute performance; Windows est axé sur l'expérience utilisateur

    Unix a démarré dans la salle des serveurs: pas d’interface utilisateur. Les utilisateurs ne voient que la vitesse. Par conséquent, la vitesse est une priorité.

    Windows a démarré sur le bureau: les utilisateurs ne se préoccupent que de ce qu'ils voient et voient l'interface utilisateur. Par conséquent, plus d'énergie est dépensée pour améliorer l'interface utilisateur que les performances.

  4. L'écosystème Windows dépend de l'obsolescence prévue. Pourquoi optimiser les logiciels alors qu’un nouveau matériel n’est qu’à un ou deux ans?

    Je ne crois pas aux théories du complot, mais si je le faisais, je ferais remarquer que, dans la culture Windows, les incitations à améliorer les performances sont moins nombreuses. Les modèles commerciaux Windows dépendent de l’achat de nouvelles machines, comme une horloge. (C’est pourquoi le prix des actions de milliers d’entreprises est affecté si MS envoie un système d’exploitation en retard ou si Intel manque une date de sortie de la puce.). Cela signifie qu'il est incité à résoudre les problèmes de performances en incitant les utilisateurs à acheter du nouveau matériel; pas en améliorant le vrai problème: les systèmes d'exploitation lents. Unix vient d'universitaire où le budget est serré et vous pouvez obtenir votre doctorat en inventant un nouveau moyen de rendre les systèmes de fichiers plus rapides. Il est rare que des universitaires aient des points pour résoudre un problème en émettant un bon de commande. Sous Windows, il n’ya pas de complot pour ralentir les logiciels, mais tout l’écosystème dépend de l’obsolescence prévue.

    De plus, comme Unix est open source (même si ce n’était pas le cas, tout le monde y avait accès), tout doctorant ennuyé peut lire le code et devenir célèbre en le rendant meilleur. Cela ne se produit pas sous Windows (MS a un programme qui donne aux universitaires l’accès au code source de Windows, il est rarement exploité). Regardez cette sélection d'articles sur les performances liées à Unix: http://www.eecs.harvard.edu/margo/papers/ ou consultez l'historique des articles écrits par Osterhaus, Henry Spencer ou autres. Heck, l'un des débats les plus importants (et les plus agréables à suivre) de l'histoire d'Unix a été le va-et-vient entre Osterhaus et Selzer http://www.eecs.harvard.edu/margo/papers/usenix95-lfs/ supplement/rebuttal.html Vous ne voyez pas ce genre de chose se produire dans le monde Windows. Vous verrez peut-être les fournisseurs se nouer les uns les autres, mais cela semble être beaucoup plus rare ces derniers temps, car l'innovation semble concerner tous les organismes de normalisation.

C'est comme ça que je le vois.

Mise à jour: Si vous regardez les nouvelles chaînes de compilateur qui sortent de Microsoft, vous serez très optimiste, car une grande partie de ce qu'elles font le rend plus facile de garder toute la chaîne d’outils dans RAM et de répéter moins de travail. Des choses très impressionnantes.

15
TomOnTime

Liaison incrémentale

Si la solution VC 2008 est configurée en plusieurs projets avec des sorties .lib, vous devez définir "Utiliser les entrées de dépendance de bibliothèque"; Cela crée un lien direct entre l'éditeur de liens et les fichiers .obj plutôt que le .lib. (Et en fait le lien progressivement.)

Performance de traversée de répertoire

Il est un peu injuste de comparer l’exploration de répertoires sur la machine d’origine avec l’exploration d’un répertoire nouvellement créé avec les mêmes fichiers sur une autre machine. Si vous voulez un test équivalent, vous devriez probablement faire une autre copie du répertoire sur la machine source. (Cela peut être encore lent, mais cela peut être dû à un certain nombre de choses: fragmentation du disque, noms de fichiers courts, services en arrière-plan, etc.) Bien que je pense que les problèmes de perf pour dir /s ont plus à voir avec l'écriture de la sortie performance de traversée de fichier. Même dir /s /b > nul est lent sur ma machine avec un énorme répertoire.

7
MSN

Je suis sûr que c'est lié au système de fichiers. Je travaille sur un projet multiplate-forme pour Linux et Windows où tout le code est commun, sauf dans les cas où le code dépendant de la plate-forme est absolument nécessaire. Nous utilisons Mercurial, pas git, donc le "Linuxness" de git ne s'applique pas. Obtenir des modifications depuis le référentiel central prend toujours plus de temps que Windows par rapport à Linux, mais je dois dire que nos machines Windows 7 sont bien meilleures que celles de Windows XP. Compiler le code après cela est encore pire sur VS 2008. Ce n’est pas juste hg; CMake fonctionne également beaucoup plus lentement sous Windows, et ces deux outils utilisent le système de fichiers plus que toute autre chose.

Le problème est si grave que la plupart de nos développeurs travaillant dans un environnement Windows ne se donnent même plus la peine de créer des versions incrémentielles: ils trouvent que faire une version unitaire à la place est plus rapide.

Incidemment, si vous voulez augmenter considérablement la vitesse de compilation sous Windows, je suggérerais la construction d'unité susmentionnée. Il est difficile d’implémenter correctement dans le système de compilation (je l’ai fait pour notre équipe dans CMake), mais une fois cela fait, cela accélère automatiquement les choses pour nos serveurs d’intégration continue. En fonction du nombre de fichiers binaires créés par votre système de compilation, vous pouvez obtenir une amélioration de 1 à 2 ordres de grandeur. Votre kilométrage peut varier. Dans notre cas, je pense que les versions Linux et Windows ont été multipliées par 10 environ, mais nous avons beaucoup de bibliothèques partagées et d’exécutables (ce qui réduit les avantages de la construction à l’unité).

6
Átila Neves

Comment construisez-vous votre grand projet multiplateforme? Si vous utilisez des makefiles courants pour Linux et Windows, vous pourriez facilement dégrader les performances de Windows d'un facteur 10 si les makefiles n'étaient pas conçus pour être rapides sous Windows.

Je viens de corriger certains fichiers Make d'un projet multiplateforme à l'aide de fichiers Make (GNU) communs pour Linux et Windows. Make lance un processus sh.exe pour chaque ligne d'une recette, ce qui entraîne une différence de performances entre Windows et Linux!

Selon le GNU faire de la documentation 

.ONESHELL:

devrait résoudre le problème, mais cette fonctionnalité n’est (actuellement) pas prise en charge par Windows. Donc, réécrire les recettes sur une seule ligne logique (par exemple, en ajoutant; ou à la fin des lignes de l'éditeur en cours) a très bien fonctionné!

5
V15I0N

IMHO c'est tout sur les performances d'E/S du disque. L’ordre de grandeur suggère que de nombreuses opérations sont exécutées sur le disque sous Windows alors qu’elles sont gérées en mémoire sous Linux, c’est-à-dire que la mise en cache est meilleure. Votre meilleure option sous Windows sera de déplacer vos fichiers sur un disque rapide, un serveur ou un système de fichiers. Pensez à acheter un disque SSD ou à transférer vos fichiers sur un disque mémoire ou un serveur NFS rapide. 

J'ai exécuté les tests de traversée de répertoires et les résultats sont très proches des temps de compilation rapportés, ce qui suggère que cela n'a rien à voir avec les temps de traitement du processeur ou les algorithmes de compilation/de création de liens.

Les temps mesurés, comme suggéré ci-dessus, parcourant l'arborescence de répertoires chrome:

  • Windows Home Premium 7 (8 Go de RAM) sur NTFS: 32 secondes
  • Ubuntu 11.04 Linux (2 Go de RAM) sur NTFS: 10 secondes 
  • Ubuntu 11.04 Linux (2 Go de RAM) sur ext4: 0,6 seconde 

Pour les tests, j'ai tiré les sources de chrome (les deux sous win/linux) 

git clone http://github.com/chromium/chromium.git 
cd chromium
git checkout remotes/Origin/trunk 

Pour mesurer le temps que j'ai couru

ls -lR > ../list.txt ; time ls -lR > ../list.txt # bash
dir -Recurse > ../list.txt ; (measure-command { dir -Recurse > ../list.txt }).TotalSeconds  #Powershell

J'ai désactivé les horodatages d'accès, mon scanner de virus et augmenté les paramètres du gestionnaire de cache sous Windows (> 2 Go de RAM) - le tout sans aucune amélioration notable. Le fait est que Linux a été 50 fois plus performant que Windows avec un quart de la RAM. 

Pour quiconque veut prétendre que les chiffres sont erronés - pour une raison quelconque - essayez-le et affichez vos résultats.

4
b7kich

Essayez d'utiliser jom au lieu de nmake

Obtenez-le ici: http://qt.gitorious.org/qt-labs/jom

Le fait est que nmake n’utilise qu’un de vos cœurs, jom est un clone de nmake qui utilise des processeurs multicœurs.

GNU fait cela immédiatement grâce à l’option -j, ce qui pourrait expliquer sa vitesse par rapport à celle de Microsoft.

jom fonctionne en exécutant en parallèle différentes commandes de commande sur différents processeurs/cœurs . Essayez vous-même et ressentez la différence!

2
OpenNingia

Je souhaite ajouter une seule observation à l'aide de Gnu make et d'autres outils d'outils MinGW sous Windows: ils semblent résoudre les noms d'hôtes même lorsque les outils ne peuvent même pas communiquer via IP. Je suppose que cela est dû à une routine d’initialisation du moteur d’exécution MinGW. L'exécution d'un proxy DNS local m'a aidé à améliorer la vitesse de compilation avec ces outils.

Auparavant, j'avais très mal à la tête parce que la vitesse de création avait été multipliée par 10 lorsque j'ai ouvert une connexion VPN en parallèle. Dans ce cas, toutes ces recherches DNS sont passées par le VPN.

Cette observation pourrait également s’appliquer à d’autres outils de compilation, pas uniquement à MinGW, et aurait pu changer entre-temps avec la dernière version de MinGW.

1
V15I0N

J'ai récemment pu archiver un autre moyen d'accélérer la compilation d'environ 10% sur Windows à l'aide de Gnu make en remplaçant le mingw bash.exe par la version de win-bash

(Le win-bash n'est pas très à l'aise avec l'édition interactive.)

0
V15I0N