Ich weiß, dass dies nicht so sehr eine Programmierfrage ist, aber sie ist relevant.
Ich arbeite an einem ziemlich großen Cross-Plattform-Projekt . Unter Windows verwende ich VC++ 2008. Unter Linux verwende ich gcc. Das Projekt enthält rund 40.000 Dateien. Windows ist 10x bis 40x langsamer als Linux beim Kompilieren und Verknüpfen desselben Projekts. Wie kann ich das beheben?
Ein einzelner Änderungsschritt dauert 20 Sekunden unter Linux und> 3 Minuten unter Windows. Warum? Ich kann sogar den "Gold" -Linker in Linux installieren und diese Zeit auf 7 Sekunden reduzieren.
Ähnlich ist git unter Linux 10x bis 40x schneller als Windows.
Im Falle von git ist es möglich, dass git Windows nicht optimal nutzt, sondern VC++? Sie würden denken, Microsoft würde ihre eigenen Entwickler so produktiv wie möglich machen wollen, und eine schnellere Kompilierung würde einen großen Beitrag dazu leisten. Vielleicht versuchen sie Entwickler zu C # zu ermutigen?
Suchen Sie als einfachen Test einen Ordner mit vielen Unterordnern und führen Sie einen einfachen aus
dir /s > c:\list.txt
unter Windows. Machen Sie es zweimal, und legen Sie den zweiten Mal fest, damit er vom Cache ausgeführt wird. Kopieren Sie die Dateien nach Linux und führen Sie die äquivalenten 2 Durchläufe aus und legen Sie den zweiten Durchlauf fest.
ls -R > /tmp/list.txt
Ich habe 2 Arbeitsplätze mit den exakt gleichen Spezifikationen. HP Z600 mit 12 g RAM, 8 Kerne bei 3,0 GHz. Bei einem Ordner mit ~ 400.000 Dateien dauert Windows 40 Sekunden, für Linux <1 Sekunde.
Gibt es eine Registrierungseinstellung, mit der ich Windows beschleunigen kann? Was gibt?
Einige leicht relevante Links, die für die Kompilierzeit relevant sind, müssen nicht unbedingt I/O sein.
Anscheinend ist es gibt ein Problem in Windows 10 (nicht in Windows 7), dass das Schließen eines Prozesses eine globale Sperre hat . Beim Kompilieren mit mehreren Kernen und daher mit mehreren Prozessen tritt dieses Problem auf.
Die Option /analyse
kann die Leistung beeinträchtigen, da ein Webbrowser geladen wird . (Nicht relevant hier, aber gut zu wissen)
Wenn kein Hardcore-Hacker für Windows-Systeme kommt, werden Sie nicht mehr als parteiische Kommentare (was ich nicht tun werde) und Spekulationen bekommen (was ich auch versuchen werde).
Dateisystem - Sie sollten die gleichen Operationen (einschließlich dir
) auf demselben Dateisystem ausführen. Ich bin auf this gestoßen, das einige Dateisysteme für verschiedene Parameter testet.
Caching Ich habe einmal versucht, eine Kompilierung unter Linux auf einer RAM -Diskette auszuführen, und stellte fest, dass diese langsamer war als die Ausführung auf Diskette, da der Kernel das Caching übernimmt. Dies ist ein solides Verkaufsargument für Linux und könnte der Grund sein, warum die Leistung so unterschiedlich ist.
Ungültige Abhängigkeitsspezifikationen unter Windows. Möglicherweise sind die Chromabhängigkeitsspezifikationen für Windows nicht so korrekt wie für Linux. Dies kann zu unnötigen Kompilierungen führen, wenn Sie eine kleine Änderung vornehmen. Sie können dies möglicherweise mit derselben Compiler-Toolchain unter Windows überprüfen.
Ein paar Ideen:
fsutil behavior set disable8dot3 1
fsutil behavior set mftzone 2
Ändern Sie die letzte Zahl in 3 oder 4, um die Größe um weitere 12,5% -Schritte zu erhöhen. Nachdem Sie den Befehl ausgeführt haben, führen Sie einen Neustart durch und erstellen Sie das Dateisystem.fsutil behavior set disablelastaccess 1
fsutil behavior set memoryusage 2
NTFS speichert jedes Mal den Dateizugriff. Sie können versuchen, es zu deaktivieren: "Fsutil behaviour disablelastaccess 1".
Das Problem mit Visual C++ ist, soweit ich das beurteilen kann, keine Priorität für das Compiler-Team, dieses Szenario zu optimieren. Ihre Lösung besteht darin, dass Sie die vorkompilierte Header-Funktion verwenden. Dies ist, was Windows-spezifische Projekte gemacht haben. Es ist nicht tragbar, aber es funktioniert.
Darüber hinaus verfügen Sie unter Windows normalerweise über Virenscanner sowie über Systemwiederherstellungs- und Suchtools, die Ihre Buildzeiten vollständig ruinieren können, wenn sie Ihren Buid-Ordner für Sie überwachen. Windows 7 Resouce Monitor kann Ihnen helfen, es zu erkennen ... Ich habe eine Antwort hier / mit einigen weiteren Tipps zur Optimierung von vc ++ - Builds, wenn Sie wirklich interessiert sind.
Ich persönlich fand heraus, dass das Ausführen einer virtuellen Windows-Maschine unter Linux einen großen Teil der IO - Langsamkeit in Windows entfernt hat, wahrscheinlich, weil die Linux-VM viele Zwischenspeicherungen durchführt, die Windows selbst nicht war.
Dadurch konnte ich die Kompilierungszeiten eines großen (250Kloc) C++ - Projekts, an dem ich arbeitete, von etwa 15 Minuten auf etwa 6 Minuten beschleunigen.
Die Schwierigkeit dabei liegt in der Tatsache, dass C++ dazu neigt, sich selbst zu verbreiten, und dem Kompilierungsprozess über viele kleine, einzelne Dateien. Das kann Linux und Windows nicht. Wenn Sie einen wirklich schnellen C++ - Compiler für Windows erstellen möchten, versuchen Sie, alles in RAM zu belassen, und berühren Sie das Dateisystem so wenig wie möglich.
Auf diese Weise können Sie auch eine schnellere Linux C++ - Kompilierungskette erstellen. Unter Linux ist dies jedoch weniger wichtig, da das Dateisystem bereits viele dieser Optimierungen für Sie vornimmt.
Der Grund dafür liegt in der Unix-Kultur: In der Vergangenheit hatte die Leistung des Dateisystems in der Unix-Welt eine viel höhere Priorität als in Windows. Ganz zu schweigen davon, dass es unter Windows keine Priorität gab, sondern dass es unter Unix eine höhere Priorität hatte.
Zugriff auf den Quellcode.
Sie können nicht ändern, was Sie nicht kontrollieren können. Mangelnder Zugriff auf Windows NTFS-Quellcode bedeutet, dass die meisten Anstrengungen zur Verbesserung der Leistung durch Hardwareverbesserungen unternommen wurden. Wenn also die Leistung langsam ist, können Sie das Problem umgehen, indem Sie die Hardware verbessern: den Bus, das Speichermedium usw. Sie können nur so viel tun, wenn Sie das Problem umgehen und nicht beheben müssen.
Der Zugriff auf Unix-Quellcode (noch vor Open Source) war weiter verbreitet. Wenn Sie also die Leistung verbessern möchten, sollten Sie dies zuerst in der Software (billiger und einfacher) und dann in der Hardware tun.
Infolgedessen haben viele Menschen auf der Welt ihren Doktortitel erworben, indem sie das Unix-Dateisystem studiert und neue Wege gefunden haben, um die Leistung zu verbessern.
Unix tendiert zu vielen kleinen Dateien. Windows tendiert zu wenigen (oder einer einzelnen) großen Datei.
Unix-Anwendungen können mit vielen kleinen Dateien umgehen. Stellen Sie sich eine Software-Entwicklungsumgebung vor: Viele kleine Quelldateien, von denen jede ihren eigenen Zweck hat. In der letzten Phase (Verknüpfung) wird eine große Datei erstellt, dies ist jedoch ein kleiner Prozentsatz.
Daher verfügt Unix über hochoptimierte Systemaufrufe zum Öffnen und Schließen von Dateien, zum Scannen von Verzeichnissen usw. Die Geschichte der Unix-Forschungsarbeiten erstreckt sich über Jahrzehnte von Dateisystemoptimierungen, die sich intensiv mit der Verbesserung des Verzeichniszugriffs (Lookups und vollständige Verzeichnis-Scans), dem erstmaligen Öffnen von Dateien usw. befassen.
Windows-Anwendungen neigen dazu, eine große Datei zu öffnen, sie lange offen zu halten und sie zu schließen, wenn sie fertig ist. Denken Sie an MS-Word. msword.exe (oder was auch immer) öffnet die Datei einmal und hängt sie stundenlang an, aktualisiert interne Blöcke und so weiter. Der Wert der Optimierung des Öffnens der Datei wäre Zeitverschwendung.
In der Vergangenheit des Windows-Benchmarking und der Windows-Optimierung wurde untersucht, wie schnell lange Dateien gelesen oder geschrieben werden können. Das wird optimiert.
Leider hat sich die Softwareentwicklung in Richtung der ersten Situation entwickelt. Heck, das beste Textverarbeitungssystem für Unix (TeX/LaTeX), empfiehlt Ihnen, jedes Kapitel in einer anderen Datei abzulegen und alle zusammen einzuschließen.
Unix ist auf hohe Leistung ausgerichtet. Windows konzentriert sich auf die Benutzerfreundlichkeit
Unix wurde im Serverraum gestartet: keine Benutzeroberfläche. Das einzige, was Benutzer sehen, ist die Geschwindigkeit. Geschwindigkeit hat daher Priorität.
Windows wurde auf dem Desktop gestartet: Benutzer kümmern sich nur um das, was sie sehen, und sie sehen die Benutzeroberfläche. Daher wird mehr Energie für die Verbesserung der Benutzeroberfläche aufgewendet als für die Leistung.
Das Windows-Ökosystem hängt von der geplanten Überalterung ab. Warum Software optimieren, wenn neue Hardware nur noch ein oder zwei Jahre entfernt ist?
Ich glaube nicht an Verschwörungstheorien, aber wenn ich das täte, würde ich darauf hinweisen, dass es in der Windows-Kultur weniger Anreize gibt, die Leistung zu verbessern. Windows-Geschäftsmodelle hängen davon ab, dass neue Computer wie Uhrwerke gekauft werden. (Aus diesem Grund ist der Aktienkurs von Tausenden von Unternehmen betroffen, wenn MS ein Betriebssystem verspätet ausliefert oder Intel ein Chip-Veröffentlichungsdatum verpasst.) Dies bedeutet, dass es einen Anreiz gibt, Leistungsprobleme zu lösen, indem die Leute angewiesen werden, neue Hardware zu kaufen. nicht durch Verbesserung des eigentlichen Problems: langsame Betriebssysteme. Unix kommt aus dem akademischen Bereich, wo das Budget knapp ist und Sie Ihre Promotion erhalten können, indem Sie eine neue Methode erfinden, um Dateisysteme schneller zu machen. Nur selten erhält jemand in der Wissenschaft Punkte für die Lösung eines Problems durch die Ausstellung einer Bestellung. In Windows gibt es keine Verschwörung, um Software langsam zu halten, aber das gesamte Ökosystem hängt von der geplanten Überalterung ab.
Da es sich bei Unix um Open Source handelt (auch wenn dies nicht der Fall war, hatte jeder Zugriff auf die Quelle), kann jeder gelangweilte Doktorand den Code lesen und berühmt werden, indem er ihn verbessert. Dies ist in Windows nicht der Fall (MS verfügt über ein Programm, mit dem Akademiker auf den Windows-Quellcode zugreifen können, und das nur selten genutzt wird). Schauen Sie sich diese Auswahl von Unix-bezogenen Performance-Papieren an: http://www.eecs.harvard.edu/margo/papers/ oder schlagen Sie die Geschichte von Papieren von Osterhaus, Henry Spencer oder anderen nach. Heck, eine der größten (und unterhaltsamsten) Debatten in der Unix-Geschichte war das Hin und Her zwischen Osterhaus und Selzer http://www.eecs.harvard.edu/margo/papers/usenix95-lfs/) supplement/rebuttal.html In der Windows-Welt passiert so etwas nicht. Möglicherweise sehen Sie Anbieter, die sich messen, aber das scheint in letzter Zeit viel seltener zu sein, da die Innovation anscheinend alle auf der Ebene der Normungsgremien liegt.
So sehe ich das.
Update: Wenn Sie sich die neuen Compiler-Ketten von Microsoft ansehen, sind Sie sehr optimistisch, denn vieles, was sie tun, macht es möglich Es ist einfacher, die gesamte Toolchain in RAM zu belassen und weniger Arbeit zu wiederholen. Sehr beeindruckendes Zeug.
Wenn die Lösung VC 2008 als mehrere Projekte mit .lib-Ausgängen eingerichtet ist, müssen Sie "Use Library Dependency Inputs" (Bibliotheksabhängigkeitseingänge verwenden) festlegen. Dadurch wird der Linker direkt mit den .obj-Dateien und nicht mit der .lib verknüpft. (Und macht tatsächlich eine inkrementelle Verknüpfung.)
Es ist etwas unfair, das Crawlen von Verzeichnissen auf dem ursprünglichen Computer mit dem Crawlen eines neu erstellten Verzeichnisses mit denselben Dateien auf einem anderen Computer zu vergleichen. Wenn Sie einen gleichwertigen Test wünschen, sollten Sie wahrscheinlich eine weitere Kopie des Verzeichnisses auf der Quellmaschine erstellen. (Es kann zwar immer noch langsam sein, aber das kann an einer Reihe von Dingen liegen: Festplattenfragmentierung, kurze Dateinamen, Hintergrunddienste usw.) Obwohl ich denke, die Perf-Probleme für dir /s
haben mehr mit dem Schreiben der Ausgabe zu tun als mit dem tatsächlichen Messen Leistung beim Durchlaufen von Dateien. Selbst dir /s /b > nul
ist auf meinem Rechner mit einem großen Verzeichnis langsam.
Ich bin mir ziemlich sicher, dass es mit dem Dateisystem zusammenhängt. Ich arbeite an einem plattformübergreifenden Projekt für Linux und Windows, bei dem der gesamte Code üblich ist, außer wenn plattformabhängiger Code unbedingt erforderlich ist. Wir verwenden Mercurial, nicht Git, also gilt die "Linuxness" von Git nicht. Das Abrufen von Änderungen aus dem zentralen Repository dauert unter Windows im Vergleich zu Linux ewig, aber ich muss sagen, dass unsere Windows 7-Computer deutlich besser sind als die Windows XP -. Das Kompilieren des Codes danach ist bei VS 2008 noch schlechter. Es ist nicht nur hg; CMake läuft auch viel langsamer unter Windows und beide Tools nutzen das Dateisystem vor allem.
Das Problem ist so schlimm, dass die meisten unserer Entwickler, die in einer Windows-Umgebung arbeiten, sich nicht einmal mehr um inkrementelle Builds kümmern - sie finden dass sie stattdessen einen Unity-Build durchführen sind schneller.
Wenn Sie die Kompilierungsgeschwindigkeit unter Windows drastisch erhöhen möchten, würde ich den oben genannten Unity-Build vorschlagen. Die korrekte Implementierung im Build-System (ich habe es für unser Team in CMake gemacht) ist ein Problem, aber wenn dies einmal erledigt ist, beschleunigt es die Dinge für unsere Continuous-Integration-Server. Je nachdem, wie viele Binaries Ihr Build-System ausspuckt, können Sie eine Verbesserung um 1 bis 2 Größenordnungen erzielen. Ihre Laufleistung kann variieren. In unserem Fall glaube ich, dass der Linux-Build dreifach und der Windows-Build um einen Faktor 10 beschleunigt wurde, aber wir haben viele gemeinsam genutzte Bibliotheken und ausführbare Dateien (was die Vorteile eines Unity-Builds verringert).
Wie erstellen Sie ein großes plattformübergreifendes Projekt? Wenn Sie gängige Makefiles für Linux und Windows verwenden, können Sie die Windows-Leistung leicht um den Faktor 10 herabsetzen, wenn die Makefiles unter Windows nicht so schnell sind.
Ich habe nur einige Makefiles eines Cross-Plattform-Projekts mit gängigen (GNU) Makefiles für Linux und Windows repariert. Make startet einen sh.exe
-Prozess für jede Zeile eines Rezepts, was den Leistungsunterschied zwischen Windows und Linux verursacht!
Gemäß der GNU -Dokumentation
.ONESHELL:
sollte das Problem beheben, aber diese Funktion wird (derzeit) für Windows nicht unterstützt. Das Umschreiben der Rezepte in einzelne logische Zeilen (z. B. durch Hinzufügen von\oder\am Ende der aktuellen Editorzeilen) hat sehr gut funktioniert!
IMHO dreht sich alles um die Festplatten-E/A-Leistung. Die Größenordnung legt nahe, dass viele Operationen unter Windows auf die Festplatte geschrieben werden, während sie unter Linux im Arbeitsspeicher gehandhabt werden, d. H., Das Zwischenspeichern von Linux ist besser. Die beste Option unter Windows ist das Verschieben Ihrer Dateien auf eine schnelle Festplatte, einen Server oder ein Dateisystem. Erwägen Sie den Kauf eines Solid State-Laufwerks oder verschieben Sie Ihre Dateien auf eine Ramdisk oder einen schnellen NFS-Server.
Ich habe die Directory Traversal-Tests ausgeführt, und die Ergebnisse liegen sehr nahe an den angegebenen Kompilierungszeiten. Dies legt nahe, dass dies nichts mit CPU-Verarbeitungszeiten oder Compiler/Linker-Algorithmen zu tun hat.
Gemessene Zeiten wie oben beim Durchqueren des Chrom-Verzeichnisbaums vorgeschlagen:
Für die Tests habe ich die Chromquellen gezogen (beide unter win/linux)
git clone http://github.com/chromium/chromium.git
cd chromium
git checkout remotes/Origin/trunk
Um die Zeit zu messen, die ich lief
ls -lR > ../list.txt ; time ls -lR > ../list.txt # bash
dir -Recurse > ../list.txt ; (measure-command { dir -Recurse > ../list.txt }).TotalSeconds #Powershell
Ich habe Zugriffszeitstempel, meinen Virenscanner deaktiviert und die Cache-Manager-Einstellungen unter Windows (> 2 GB RAM) erhöht - alles ohne merkliche Verbesserungen. Tatsache ist, dass Linux 50x besser war als Windows mit einem Viertel des Arbeitsspeichers.
Für jeden, der behaupten will, dass die Zahlen falsch sind - aus welchem Grund auch immer -, probieren Sie es bitte aus und veröffentlichen Sie Ihre Ergebnisse.
Versuchen Sie es mit jom anstelle von nmake
Laden Sie es hier herunter: http://qt.gitorious.org/qt-labs/jom
Tatsache ist, dass nmake nur einen Ihrer Kerne verwendet. Jom ist ein Klon von nmake, der Multicore-Prozessoren verwendet.
GNU macht dies dank der Option -j sofort möglich, was möglicherweise ein Grund für seine Geschwindigkeit im Vergleich zu Microsoft ist.
jom führt verschiedene make-Befehle auf verschiedenen Prozessoren/Kernen parallel aus. Testen Sie sich selbst und fühlen Sie den Unterschied!
Ich möchte nur eine Beobachtung mit Gnu make und anderen Tools von MinGW-Tools unter Windows hinzufügen: Sie scheinen Hostnamen aufzulösen, selbst wenn die Tools nicht einmal über IP kommunizieren können. Ich würde vermuten, dass dies durch eine Initialisierungsroutine der MinGW-Laufzeit verursacht wird. Durch das Ausführen eines lokalen DNS-Proxys konnte ich die Kompilierungsgeschwindigkeit mit diesen Tools verbessern.
Vorher hatte ich große Kopfschmerzen, weil die Build-Geschwindigkeit um den Faktor 10 abnahm, als ich eine VPN-Verbindung parallel aufbaute. In diesem Fall wurden alle diese DNS-Suchen über das VPN durchgeführt.
Diese Beobachtung könnte sich auch auf andere Build-Tools beziehen, die nicht nur auf MinGW basieren und sich in der letzten MinGW-Version geändert haben könnten.
Ich konnte kürzlich eine andere Möglichkeit zur Beschleunigung der Kompilierung unter Windows mit Gnu make um etwa 10% verwenden, indem ich die Datei mingw bash.exe durch die Version aus win-bash
(Die Win-bash ist in Bezug auf interaktives Editieren nicht sehr komfortabel.)