Langsames Windows, Teil 2: Erstellen von Prozessen

Published on October 22, 2018

Langsames Windows, Teil 2: Erstellen von Prozessen

Ursprünglicher Autor: Bruce Dawson
  • Übersetzung


Windows wird seit langem für die Langsamkeit von Dateivorgängen und Erstellungsprozessen verantwortlich gemacht. Haben Sie jemals versucht, sie noch langsamer zu machen? Dieser Artikel zeigt dem Techniker, wie er die Erstellung von Prozessen in Windows (bis unendlich) für die meisten Benutzer unmerklich verlangsamen 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 zum Verlangsamen von Windows:


Stimmt etwas nicht


Ich suche keine Probleme, aber es scheint, als hätte ich sie gefunden. Vielleicht, weil ich über ein Wochenende hundert Mal Chrome aus dem Quellcode sammle, oder weil ich in meinem Leben kein Glück habe. Ich denke, wir werden es nie erfahren. In diesem Artikel wird das fünfte schwerwiegende Problem beschrieben, auf das ich beim Erstellen von Chrome in Windows gestoßen bin.

  1. Ungeplante Serialisierung, die zu einem vollständigen UI-Hang führt: "24-Core-Prozessor, und ich kann den Cursor nicht bewegen . "
  2. Ein Prozess-Handle-Leck in einem der Microsoft-Add-Ons für Windows: "Zombie-Prozesse verschlingen Ihren Speicher . "
  3. Langzeitfehler im Windows-Dateicache: „Compiler-Fehler? Linker Fehler? Windows-Kernel-Fehler .
  4. Leistungsfehler aufgrund eines Missbrauchs von Dateibenachrichtigungen: "Langsames Windows, Teil 1: Dateizugriff . "
  5. Und das: eine seltsame architektonische Lösung, die mit der Zeit die Entstehung von Prozessen verlangsamt.

Verfolgung eines seltenen Absturzes


Computer müssen zuverlässig und vorhersehbar sein, und ich ärgere mich sonst. Wenn ich Chrome mehrere hundert Mal hintereinander sammle, möchte ich, dass jeder Build erfolgreich ist. Wenn unser verteilter Kompilierungsprozess (gomacc.exe) manchmal abstürzt, möchte ich das untersuchen. Ich habe das automatische Ausgeben von Absturzabbildern konfiguriert , sodass Abstürze auftreten, wenn Heap-Schäden festgestellt werden. Eine einfache Möglichkeit, dies zu überprüfen, besteht darin, den Seitenhaufen einzuschalten, sodass eine Reihe von Windows jede Speicherzuweisung auf einer separaten Seite ablegt. Dies bedeutet, dass ein nachträglicher Gebrauch und Pufferüberläufe zu einem sofortigen Ausfall führen und keine schwer zu diagnostizierenden Schäden verursachen. Ich habe bereits über die Einbeziehung von PageHeap mithilfe von App Verifier geschrieben .

App Verifier verlangsamt das Programm aus zwei Gründen: Die Speicherzuweisung verlangsamt sich und die seitenbezogene Zuweisung deaktiviert praktisch den Cache des Prozessors. Daher war eine leichte Verlangsamung der Montage vorhersehbar, und das tat es auch.

Aber als ich später eintrat, schien die Versammlung ganz aufzuhören. Nach rund 7.000 Montageschritten waren keine Fortschritte zu verzeichnen.

O (n ^ 2) - das ist normalerweise nicht gut


Es stellt sich heraus, dass Application Verifier gerne Protokolldateien erstellt. Es ist egal, dass sich niemand diese Dateien ansieht, er erstellt sie nur für den Fall. 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, z. B. gomacc.exe.0.dat, gomacc.exe.1.dat und so weiter.

Um die numerischen Namen in aufsteigender Reihenfolge zu erhalten, müssen Sie festlegen, 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, und versuchen Sie es mit gomacc.exe.1.dat usw., falls diese bereits vorhanden ist.

Was kann schief gehen?

Im schlimmsten Fall ist alles ziemlich schlecht.


Wenn Sie beim Erstellen eines Prozesses eine lineare Suche nach einem nicht verwendeten Dateinamen durchführen, werden beim Starten von N Prozessen O (N ^ 2) -Operationen ausgeführt. 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 sein wird, hängt davon ab, wie lange es dauert, die Existenz einer Datei zu überprüfen. Ich habe Messungen durchgeführt und festgestellt, dass Windows etwa 80 Mikrosekunden (80 μs oder 0,08 ms) benötigt. Der Start des ersten Prozesses ist schnell, aber der Start 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 ungefähr 30.000 Mal ausgeführt werden. Jeder Compiler-Lauf erfordert das Scannen von N zuvor erstellten Protokolldateien (0,08 ms), um jede Datei zu überprüfen. Eine lineare Suche nach dem nächsten verfügbaren Protokolldateinamen bedeutet, dass (N ^ 2) / 2-Datei-Existenzprüfungen erforderlich sind, um N Prozesse auszuführen, dh 30.000 * 30.000 / 2, was 450 Millionen entspricht. Da jede Prüfung des Vorhandenseins von Dateien 0,08 ms dauert, sind es 36 Millionen Millisekunden oder 36.000 Sekunden. Das heißt, die Build-Zeit von Chrome, die normalerweise zwischen fünf und zehn Minuten liegt, 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 ich sah eine klare O (n ^ 2) -Kurve wie diese:



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



Hier wird anscheinend nur die ETW-Grenze für den Datei-E / A-Trace angezeigt . Datei-E / A-Ereignisse verfolgen nur die unterste Ebene des Dateisystems, und über Ntfs.sys befinden sich viele weitere Ebenen, einschließlich FLTMGR.SYS und ntoskrnl.exe. Die Verlangsamung kann jedoch nicht vollständig ausgeblendet werden - die Auslastung der CPU ist in der Grafik der CPU-Auslastung ersichtlich. Der Screenshot unten zeigt das Zeitintervall von 548 ms, bei dem ein einzelner Prozess erstellt wird. Grundsätzlich wird die gesamte Zeit nur für das Scannen von etwa 6850 möglichen Protokolldateinamen aufgewendet:



Hilft eine produktivere Festplatte?


Nein.

Die verarbeitete Datenmenge ist gering, und die Menge des Schreibens auf die Festplatte ist noch geringer. Während meiner Tests zum Abspielen des Fehlers war die Festplatte fast vollständig im Leerlauf. Dies ist ein Problem mit der CPU, da alle relevanten Festplattendaten zwischengespeichert werden. Und selbst wenn die Gemeinkosten um eine Größenordnung reduziert würden, wären sie immer noch zu groß. Sie können den Algorithmus O (N ^ 2) nicht verbessern.

Erkennung


Dieses spezielle Problem kann festgestellt werden, indem in% userprofile% \ appverifierlogs nach DAT-Dateien gesucht wird. Im Allgemeinen können Sie eine Verlangsamung beim Erstellen von Prozessen feststellen, indem Sie die ETW-Ablaufverfolgung untersuchen. Jetzt wissen Sie, wonach Sie suchen müssen.

Lösung


Die einfachste Lösung besteht darin, die Protokollierung zu deaktivieren. Außerdem wird 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 begannen und die Verlangsamung vollständig verschwand. Überwachte Prozesse von 7000 Application Verifier 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 Geschwindigkeiten für das Erstellen von Prozessen:

  • in der Regel 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 aktiviertem Journaling (25 ms pro Prozess, Zeit wird allmählich unendlich)
  • 0,4 pro Sekunde nach einem einzelnen Chrome-Build

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 Auflösung von Millisekunden oder höher), erhalten sie semantisch aussagekräftigere Protokollnamen, die sehr schnell erstellt werden, ohne dass nach einer eindeutigen Datei gesucht werden muss.

Application Verifier wird jedoch nicht mehr unterstützt und Protokolldateien sind weiterhin unbrauchbar. Deaktivieren Sie sie daher einfach.

Zusatzinformationen


Batch-Dateien und ein Skript zum erneuten Erstellen des Fehlers nach dem Aktivieren von Application Verifier for empty.exe finden Sie hier .

ETW-Verfolgung von ungefähr dem Ende des Experiments - hier .

Andere Links:

Die Rohdaten der Timings verwendet , um die Grafik zu erstellen

Diskussion auf Reddit

Diskussion über Hacker News

Beispiele für andere Algorithmen O (n ^ 2), der Hawking finden. Versehentlich Quadratic

Weitere banale Freuden, siehe ‚Video - Mine. 19 verschiedene Möglichkeiten , um im September arbeiten - ich war zu beschäftigt, um das Experiment diesen Monat fortzusetzen.