
Windows wird seit langem für die Langsamkeit der Dateivorgänge und der Prozesserstellung verantwortlich gemacht. Haben Sie jemals versucht, sie noch langsamer zu machen? Dieser Artikel zeigt die Technik, wie die Erstellung von Prozessen in Windows (ad infinitum) für die meisten Benutzer unsichtbar verlangsamt werden kann!
In diesem Artikel erfahren Sie natürlich auch, wie Sie dieses Problem erkennen und vermeiden können.
Dies ist ein echtes Problem, auf das ich zu Beginn des Jahres gestoßen bin, und der Artikel erklärt, wie ich es entdeckt und eine Problemumgehung gefunden habe. Frühere Artikel zur Verlangsamung von Windows:
Stimmt etwas nicht
Ich suche keinen Ärger, aber ich glaube, ich habe sie gefunden. Vielleicht, weil ich am Wochenende hunderte Male Chrome von der Quelle sammle oder weil ich im Leben Pech habe. Ich denke, wir werden es nie erfahren. Auf die eine oder andere Weise beschreibt dieser Artikel das
fünfte schwerwiegende Problem, auf das ich beim Erstellen von Chrome in Windows gestoßen bin.
- Ungeplante Serialisierung, die zu einer vollständigen Hang-Benutzeroberfläche führt: "24-Kern-Prozessor, aber ich kann den Cursor nicht bewegen . "
- Ein Prozessdeskriptorleck in einem der Microsoft-Add-Ons für Windows: "Zombie-Prozesse verbrauchen Ihren Speicher . "
- Ein langjähriger Korrektheitsfehler im Windows-Dateicache: „Compilerfehler? Linker Fehler? Windows-Kernel-Fehler. "
- Leistungsfehler bei falscher Verwendung von Dateimeldungen : "Windows verlangsamen, Teil 1: Dateizugriff . "
- Und das: eine seltsame architektonische Lösung, die die Erstellung von Prozessen im Laufe der Zeit verlangsamt.
Seltene Crash-Tracking
Computer sollten zuverlässig und vorhersehbar sein, und etwas anderes nervt mich. Wenn ich Chrome mehrere hundert Mal hintereinander erstelle, würde ich mir wünschen, dass jede Assembly erfolgreich ist. Wenn unser verteilter Kompilierungsprozess (gomacc.exe) manchmal abstürzt, möchte ich dies untersuchen. Ich habe die
automatische Aufzeichnung von Absturzabbildern konfiguriert, sodass ich sehe, dass Abstürze auftreten, wenn eine Heap-Beschädigung erkannt wird. Eine einfache Möglichkeit zur Überprüfung besteht darin, pageheap so zu aktivieren, dass der Windows-Heap jede Speicherzuordnung auf einer separaten Seite platziert. Dies bedeutet, dass Use-After-Free- und Pufferüberläufe einen sofortigen Fehler verursachen, anstatt schwer zu diagnostizierende Schäden. Ich habe zuvor über das
Aktivieren von Pageheap mit App Verifier geschrieben .
App Verifier verlangsamt das Programm aus zwei Gründen: Speicherzuordnungen werden verlangsamt, und seitenausgerichtete Zuweisungen deaktivieren den Prozessor-Cache praktisch. Somit war eine leichte Verlangsamung der Montage vorhersehbar, und es geschah.
Aber als ich später hereinkam, schien die Versammlung ganz anzuhalten. Nach
ca. 7000 Montageschritten waren keine Fortschritte zu verzeichnen.
O (n ^ 2) ist normalerweise nicht gut
Es stellt sich heraus, dass Application Verifier gerne Protokolldateien erstellt. Und egal, dass niemand diese Dateien ansieht, er erstellt sie für alle Fälle. Und diese Dateien müssen eindeutige Namen haben. Ich bin sicher, es schien eine gute Idee zu sein, den Protokollen nur numerische Namen in aufsteigender Reihenfolge zu geben, wie z. B. gomacc.exe.0.dat, gomacc.exe.1.dat und so weiter.
Um numerische Namen in aufsteigender Reihenfolge zu erhalten, müssen Sie bestimmen, welche Nummer als Nächstes verwendet werden soll. Am einfachsten ist
es, mögliche Namen / Nummern
auszuprobieren, bis Sie einen finden, der noch nicht verwendet wurde. Versuchen Sie also, eine neue Datei mit dem Namen gomacc.exe.0.dat zu erstellen. Wenn diese bereits vorhanden ist, versuchen Sie es mit gomacc.exe.1.dat und so weiter.
Was könnte schief gehen?
In der Tat ist im schlimmsten Fall alles ziemlich schlecht
Es stellt sich heraus, dass, wenn Sie beim Erstellen eines Prozesses eine lineare Suche nach einem nicht verwendeten Dateinamen durchführen, das Starten von N Prozessen
O (N ^ 2) -Operationen erfordert. Der gesunde Menschenverstand schreibt vor, dass O (N ^ 2) -Algorithmen zu langsam sind, wenn Sie nicht garantieren können, dass N immer relativ klein bleibt.
Wie schlimm die Situation wird, hängt davon ab, wie lange es dauert, um die Existenz der Datei zu überprüfen. Ich habe Messungen durchgeführt und festgestellt, dass es unter Windows etwa 80 Mikrosekunden (80 μs oder 0,08 ms) dauert. Das Starten des ersten Prozesses ist schnell, aber das Starten des 1000. Prozesses erfordert das Scannen von 1000 bereits erstellten Protokolldateien. Es dauert 80 ms und dann noch mehr.
Bei einem typischen Chrome-Build muss der Compiler etwa 30.000 Mal ausgeführt werden. Jeder Lauf des Compilers erfordert das Scannen von N zuvor erstellten Protokolldateien, 0,08 ms zum Überprüfen jeder Datei. Eine lineare Suche nach dem nächsten verfügbaren Protokolldateinamen bedeutet, dass zum Ausführen von N Prozessen (N ^ 2) / 2 Überprüfungen auf das Vorhandensein der Datei erforderlich sind, d. H. 30.000 * 30.000 / 2, was 450 Millionen entspricht. Da jede Überprüfung des Vorhandenseins einer Datei 0,08 ms dauert, sind dies 36 Millionen Millisekunden oder 36.000 Sekunden. Das heißt, die Erstellungszeit von Chrome, die normalerweise fünf bis zehn Minuten beträgt, erhöht sich um weitere zehn Stunden.
Verdammt.
Beim Schreiben dieses Artikels habe ich den Fehler reproduziert, indem ich ungefähr 7000 Mal eine leere ausführbare Datei ausgeführt habe - und eine klare O (n ^ 2) -Kurve wie diese gesehen:

Seltsamerweise beträgt das Ergebnis für fast alle Dateien weniger als fünf Mikrosekunden (durchschnittlich 4,386 μs im folgenden Beispiel), wenn wir den ETW-Trace verwenden und die durchschnittliche Aufrufzeit von CreateFile betrachten:

Es scheint, dass dies nur die ETW-Einschränkung für die Datei-E / A-Ablaufverfolgung zeigt. Datei-E / A-Ereignisse verfolgen nur die unterste Ebene des Dateisystems, und über Ntfs.sys gibt es viel mehr Ebenen, einschließlich FLTMGR.SYS und ntoskrnl.exe. Die Verlangsamung kann jedoch nicht vollständig ausgeblendet werden. Die CPU-Auslastung wird im Diagramm zur CPU-Auslastung angezeigt. Der folgende Screenshot zeigt das Zeitintervall von 548 ms, das die Erstellung eines einzelnen Prozesses darstellt. Grundsätzlich dauert es die ganze Zeit, um ungefähr 6850 mögliche Protokolldateinamen zu scannen:

Hilft eine produktivere Festplatte?
Nein.
Die Menge der verarbeiteten Daten ist gering und das Schreiben auf die Festplatte ist noch geringer. Während meiner Tests zur Reproduktion eines Fehlers war die Festplatte fast vollständig inaktiv. Dieses Problem hängt mit der CPU zusammen, da alle relevanten Datenträgerdaten zwischengespeichert werden. Und selbst wenn die Gemeinkosten um eine Größenordnung gesenkt würden, wären sie immer noch zu hoch. Sie können den O (N ^ 2) -Algorithmus nicht verbessern.
Entdeckung
Dieses spezielle Problem kann erkannt werden, indem% userprofile% \ appverifierlogs nach .dat-Dateien durchsucht wird. Im
Allgemeinen können Sie eine Verlangsamung der Prozesserstellung feststellen, indem Sie den ETW-Trace untersuchen. Jetzt wissen Sie, wonach Sie suchen müssen.
Lösung
Die einfachste Lösung besteht darin, die Protokollierung zu deaktivieren. Dadurch wird auch die Festplatte nicht mehr mit Gigabyte an Protokollen gefüllt. Es wird durch den folgenden Befehl deaktiviert:
appverif.exe -logtofile disable
Nach dem Deaktivieren der Protokollierung stellte ich fest, dass meine Prozesse etwa dreimal schneller (!) Als zu Beginn des Tests gestartet wurden und die Verlangsamung vollständig verschwand. 7000 überwachte Application Verifier-Prozesse werden in 1,5 Minuten und nicht in 40 Minuten erstellt. Mit meiner einfachen Batchdatei für Tests und einem einfachen Prozess sehe ich die folgenden Prozesserstellungsgeschwindigkeiten:
- typischerweise 200 pro Sekunde (5 ms pro Prozess)
- 75 pro Sekunde bei aktiviertem Application Verifier, aber deaktivierter Protokollierung (13 ms pro Prozess)
- 40 pro Sekunde bei aktiviertem Application Verifier und aktivierter Protokollierung zuerst ... (25 ms pro Prozess, die Zeit steigt allmählich auf unendlich an)
- 0,4 pro Sekunde nach einem Build von Chrome
Microsoft kann dieses Problem beheben, indem die monotone Zunahme der Anzahl der Protokolldateien aufgegeben wird. Wenn sie das aktuelle Datum und die aktuelle Uhrzeit als Dateinamen verwenden (bis zu einer Millisekunde oder in höherer Auflösung), erhalten sie semantisch aussagekräftigere Namen von Protokollen, die sehr schnell erstellt werden, praktisch ohne Suchlogik für eine eindeutige Datei.
Application Verifier wird jedoch nicht mehr unterstützt und die Protokolldateien sind ohnehin unbrauchbar. Deaktivieren Sie sie einfach.
Unterstützende Informationen
Batch-Dateien und ein Skript zum erneuten Erstellen des Fehlers nach dem Aktivieren von Application Verifier für empty.exe finden Sie
hier .
Die ETW-Spur vom Ende des Experiments ist
hier .
Andere Links:
Rohe Zeitdaten, die zum Erstellen eines Diagramms verwendet werden.Diskussion über RedditDiskussion bei Hacker NewsBeispiele für andere O (n ^ 2) -Algorithmen, die hausieren, finden Sie unter
Versehentlich quadratischWeitere Informationen finden Sie in einer Video-Zusammenstellung meiner
19 verschiedenen Möglichkeiten, im September zur Arbeit zu kommen. Ich war zu beschäftigt, um das Experiment diesen Monat fortzusetzen.