Doppelt so schnell booten durch 93 mal schnelleren Festplattenzugriff?

Doppelt so schnell booten durch 93 mal schnelleren Festplattenzugriff?

Da ich mein Linux daheim ja nur alle paar Tage/Wochen neu boote, und der Rechner sonst rund um die Uhr läuft (ich darf das, ich hab 100% Ökostrom!), könnte mit die Zeit zum Booten ja eigentlich egal sein. Aber ich bin nun mal optimierungswütig, vor allem, wenn zwischen dem Ist-Zustand und dem, was ich für möglich halte, ein sehr hoher Faktor liegt. In diesem Fall denke ich, ich könnte die Geschwindigkeit der Festplattenzugriffe um einen zweistelligen Faktor erhöhen und damit den Gesamtbootvorang immerhin um 77% beschleunigen. Das motiviert, also habe ich gestern und heute ein paar Nachforschungen und Versuche angestellt. Ich möchte hier schonmal von den Ergebnissen berichten, aber auch von dem Weg dorthin, denn die offensichtlichsten Verfahren zur Messung stellten sich oft als falsch heraus.

Ausgangszustand: Normaler Bootvorgang mit ureadahead in 114 Sekunden

Mein Ubuntu bootet in 114 Sekunden. Gemessen habe ich von der Auswahl im GRUB Menü bis sich auf dem Desktop das Fenster zur Schlüsselbundentsperrung öffnet. Dies ist das letzte sichtbare Ereignis nach beim Hochfahren, so dass es sich zur Zeitnahme eignet.
Beim gesamten Bootvorgang höre ich permanent die Festplatte „knattern“, es finden scheinbar viele Lesezugriffe an verschiedenen Stellen statt. Das wollte ich genauer wissen. Mittels ureadahead konnte ich das genauer untersuchen. Dieses Programm nutzt eine Kernelerweiterung, um beim Booten alle Lesezugriffe zu protokollieren. Ich vertraue darauf, dass dies prinzipiell korrekt abläuft und habe als Ergebnis erhalten: Ubuntu liest beim Starten 226MB aus 3140 Dateien. Angeblich liegen diese an nur 3113 verschiedenen Stellen der HDD. Komisch, aber eine Abweichung, die ich akzeptieren kann.

Wie viel dieser Zeit wird zum Lesen benötigt?

Meine Platte braucht im Schnitt 20ms für eine Neupositionierung des Kopfes, für 3113 davon also rechnerisch etwa 65 Sekunden. Die Zeit, die das eigentliche Lesen braucht, ist im Vergleich dazu zu vernachlässigen: rechnerisch 2,8 Sekunden auf dieser Partition, oder sogar nur 1,4 Sekunden wenn ich die erste Partition verwenden würde, da diese doppelt so schnell liest. (Liegt daran, dass sich die Platte am äußeren Rand schneller unter dem Lesekopf bewegt als innen.)
Aber wie viel ist dran an dieser Rechnung? Kann ich die Lesezeiten nicht auch direkt messen? Ja, ich kann. Mittels „ureadahead –dump“ kann ich mir eine Liste der Dateien ausgeben. Zugegebermaßen, diese Dateien sind in der Summe 300 MB groß, beim booten werden aber nur 226 MB gelesen, da nicht alle Dateien komplett gebraucht werden. Bei den weiteren Messungen verwende ich stets diese 300MB Dateien komplett.
Mit ein bisschen Textersetzung erhalte ich aus der Dateiliste ein Skript, das nacheinander jede dieser Dateien nach /dev/null kopiert. Ich messe also mittels „time“ die Ausführungszeit. 13,5 Sekunden? Da stimmt was nicht, das geht zu schnell. Ich messe nochmal: Diesmal nur noch 4,5 Sekunden!
Aber klar doch, die Dateien sind noch im Lesecache. Also diesen mal schnell mit

sync && echo 3 > /proc/sys/vm/drop_caches

leeren und nochmal messen. Ergebnis: 63,44 Sekunden. Das stimmt doch erstaunlich gut mit den berechneten 65 Sekunden überein.

Kann ich das auf 2,6 Sekunden reduzieren?

Die Frage ist jetzt: Wie kann ich das Lesen dieser Dateien auf die 2,6 Sekunden beschleunigen, die es dauern würde, wenn diese am Stück hintereinander stehen würden? Die Lösung: ich schreibe sie am Stück hintereinander 🙂 Also kopiere ich all diese Dateien in ein neu angelegtes Verzeichnis. Anschließend leere ich wieder den Cache und lese all diese Dateien nacheinander ein. Statt 63,44 Sekunden braucht dies nur noch 31,49 Sekunden. Aber immer noch deutlich länger als erwartet. Dummerweise habe ich die Dateien in einer anderen Reihenfolge geschrieben, als ich sie nun gelesen habe. Also ein neuer Versuch, diesmal in gleicher Reihung geschrieben und dann gelesen, dazwischen natürlich wieder den Cache geleert. Und siehe da: 16,8 Sekunden. Eine Beschleunigung von 74% allein dadurch, dass die Dateien in der richtigen Reihenfolge hintereinander auf der Platte stehen.
Was aber, wenn ich sie mittels tar komplett zu einer Datei vereinige? Dann kann ich sie in 7,69 Sekunden einlesen. Und gepackt als .tar.gz dauert es sogar nur noch 1,8 Sekunden. Aber auch diese Datei liegt nun am langsamen Ende meiner Festplatte, am schnellen Ende wäre ich somit bei 0,9 Sekunden.Mir ist dabei übrigens total unklar, warum die .tar.gz 4,2 mal so schnell gelesen wird obwohl sie nur um den Faktor 2,7 kleiner ist. Wiederholte Messungen haben das aber bestätigt.

Was nützt schnelles Lesen, wenn die Daten dann gepackt sind?

Aber die Daten müssen ja nach bzw. während des Lesens noch entpackt werden, und zwar in den Arbeitsspeicher. Das dauert auf die naive Art und Weise 3,1 Sekunden, also deutlich länger, als die Daten ungezippt zu lesen. Dabei wird aber nur ein Kern benutzt. Es wäre aber einfach möglich, alle Kerne damit auszulasten. In meinem Fall mit zwei Kernen würde der Lesevorgang auf 1,55 Sekunden verkürzt, mit vier Kernen wäre das Entpacken schneller als das Lesen, so dass das theoretische Optimum von 0,9 Sekunden erreicht wird. Bekanntlich lese ich dabei ja komprimierte Dateien ein, die entpackt 300 MB ergeben, von denen ich aber nur 226 MB wirklich verwende. Ich war zu faul, für die Messung die richtigen 226MB zu extrahieren, aber wenn man hochrechnet, kommt man auf 0,678 Sekunden für das Lesen der benötigten Daten, immerhin ein Faktor von 93.

Fazit

Ich weiß, wie ich das Lesen der zum Booten benötigten Dateien von 63,44 Sekunden auf 0,678 Sekunden beschleunigen könnte, was den Bootvorgang vermutlich von auf die Hälfte verkürzen würde. Die nötigen Operationen habe ich im laufenden System getestet. Jetzt müsste ich „nur noch“ herausfinden, wie ich das praktisch in den Bootvorgang einbinden kann… Das wird sehr wahrscheinlich meine Fähigkeiten und Kenntnisse übersteigen – aber vielleicht können meine Messungen ja jemand schlaueres dazu motivieren, sich des Themas anzunehmen. Offenbar ist ja noch einiges herauszuholen.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.