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.
Apparemment, il existe un problème dans Windows 10 (et non dans Windows 7) selon lequel la fermeture d'un processus entraîne un verrou global . Lors de la compilation avec plusieurs cœurs et par conséquent plusieurs processus, ce problème se pose.
_ { L'option /analyse
peut avoir un impact négatif sur perf car elle charge un navigateur Web } _. (Non pertinent ici mais bon à savoir)
À 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).
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.
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.
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.
Quelques idées:
fsutil behavior set disable8dot3 1
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.fsutil behavior set disablelastaccess 1
fsutil behavior set memoryusage 2
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)
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é.
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.
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.
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.
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.
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.
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.
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.)
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.
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é).
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é!
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:
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.
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!
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.
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.)