Erzwinge, dass sich das Verzeichnis immer im Cache befindet


35

Ich habe verschiedene Methoden getestet, um die Kompilierungszeit meines gesamten c ++ - Projekts zu verkürzen. Derzeit dauert es ca. 5 Minuten. Ich habe mit distcc, ccache und anderen experimentiert. Kürzlich entdeckte ich, dass, wenn ich mein gesamtes Projekt auf ein RAM-Laufwerk kopiere und von dort kompiliere, die Kompilierzeit auf 30% der ursprünglichen Zeit reduziert wird - nur 1,5 Minuten.

Es ist offensichtlich nicht praktisch, vom RAM-Laufwerk aus zu arbeiten. Weiß jemand, wie ich das Betriebssystem zwingen kann , ein bestimmtes Verzeichnis immer im Cache zu halten ? Ich möchte weiterhin, dass das Verzeichnis wie gewohnt wieder auf die Festplatte synchronisiert wird, aber ich möchte immer auch eine Kopie der Daten im Speicher. Ist das möglich?

BEARBEITEN: Als mögliche Lösung haben wir uns gerade überlegt, einen Dämon zu starten, der etwa rsyncalle 10 Sekunden ausgeführt wird, um das Festplattenlaufwerk mit einem RAM-Laufwerk zu synchronisieren. Dann führen wir die Kompilierung vom RAM-Laufwerk aus. Das rsyncist blitzschnell, aber würde das wirklich funktionieren? Sicher könnte das Betriebssystem besser sein ...


Cache ist nicht der einzige Unterschied zwischen tmpfs und ext3 / 4. Sie haben zum Beispiel ein Journal, das unabhängig vom Caching geschrieben wird.
André Paramés

1
Könnten Sie timeIhre Zusammenstellung und das Ergebnis mit uns teilen? Es würde einige Kontroversen zerstreuen. make clean && /usr/bin/time -v make(Verwenden Sie nicht den eingebauten timeBefehl bash )
Shellholic

1
@she Warum nicht den eingebauten Befehl von bash?
Tshepang

3
@ Tshepang die timeeingebaute Bash ( help time) hat viel weniger Details (keine ausführliche Option) als die GNU-Zeit ( man time) in Bezug auf die E / A, Kontext-Schalter, ...
Shellholic

Antworten:


18

Die naheliegende Möglichkeit, eine Reihe von Dateien im Cache zu behalten, besteht darin, häufig darauf zuzugreifen. Linux ist ziemlich gut darin, zwischen Tauschen und Zwischenspeichern zu entscheiden, daher vermute ich, dass der beobachtete Geschwindigkeitsunterschied nicht darauf zurückzuführen ist, dass das Betriebssystem die Dinge nicht im Cache hält, sondern auf einen anderen Unterschied zwischen Ihrer Verwendung von tmpfs und Ihren anderen Versuchen.

Beobachten Sie in jedem Fall, was IO tut. Das grundlegende Werkzeug dafür ist iotop. Andere Tools können nützlich sein. Siehe Linux Disk IO Load Breakdown, nach Dateisystempfad und / oder Prozess? , Welches Programm in Linux kann I / O über die Zeit messen? und andere Threads bei Serverfehler.

Hier einige Hypothesen, was passieren könnte. Wenn Sie Messungen vornehmen, zeigen Sie diese bitte vor, damit wir diese Hypothesen bestätigen oder widerlegen können.

  • Wenn Sie die Dateizugriffszeiten aktiviert haben , wird das Betriebssystem möglicherweise viel Zeit mit dem Schreiben dieser Zugriffszeiten verschwenden. Zugriffszeiten sind für einen Kompilierungsbaum unbrauchbar. Stellen Sie daher sicher, dass sie mit der noatimeMount-Option deaktiviert sind. Ihre tmpfs + rsync-Lösung liest nie von der Festplatte, so dass Sie nie mehr Zeit für das Schreiben aufwenden müssen.
  • Wenn die Schreibvorgänge synchronisiert werden , weil der Compiler sie aufruft sync()oder weil der Kernel häufig seine Ausgabepuffer leert, dauert das Schreiben auf eine Festplatte länger als auf tmpfs.

Ich habe auch dieses Gefühl. Das Kompilieren ist eher CPU-intensiv als IO.
Phunehehe

Hmmm, ich würde gerne einen Kommentar von @JaredC sehen, der die Gilles-Hypothese bestätigt oder ablehnt. 1,5 gegen 5 Minuten ist ein ziemlicher Unterschied ...
Daniel Alder

8

Linux verwendet standardmäßig den RAM als Festplatten-Cache. Versuchen Sie zur Demonstration, time find /some/dir/containing/a/lot/of/files > /dev/nullzwei Mal auszuführen . Das zweite Mal ist viel schneller, da alle Festplatten-Inodes zwischengespeichert werden. Der Punkt hier ist, wie Sie diese Kernel-Funktion nutzen und Ihren Versuch, sie zu ersetzen, beenden können.

Es geht darum, das zu ändern swappiness. Wir betrachten drei Haupttypen der Speichernutzung: aktive Programme, inaktive Programme und Festplatten-Cache. Offensichtlich sollte der von aktiven Programmen verwendete Speicher nicht ausgelagert werden, und die Wahl zwischen zwei anderen ist ziemlich willkürlich. Möchten Sie eine schnelle Programmumschaltung oder einen schnellen Dateizugriff? Eine niedrige Auslagerungsrate zieht es vor , Programme im Speicher zu belassen (auch wenn sie längere Zeit nicht verwendet werden), und eine hohe Auslagerungsrate zieht es vor , mehr Festplatten-Cache zu belassen (indem nicht verwendete Programme ausgetauscht werden). (Die Swappiness-Skala reicht von 0 bis 100 und der Standardwert ist 60)

Meine Lösung für Ihr Problem besteht darin, die Swap-Einstellung auf sehr hoch zu setzen (90-95, nicht 100) und den Cache zu laden:

echo 95 | sudo tee /proc/sys/vm/swappiness > /dev/null # once after reboot
find /your/source/directory -type f -exec cat {} \; > /dev/null

Wie Sie sich vorstellen können, müssen Sie über genügend freien Speicher verfügen, um alle Ihre Quell- und Objektdateien sowie den Compiler im Cache zu speichern, einschließlich Header-Dateien, verknüpfter Bibliotheken, Ihrer IDE und anderer verwendeter Programme.


Dies ist im Allgemeinen nützlich, aber was ich wirklich möchte, ist, dass mein Quellcode eine geringe Auslagerung aufweist, während alles andere eine normale Auslagerung aufweist. Im Grunde läuft im Hintergrund viel, aber ich möchte sie auf 6 von 8 GB beschränken, während ich immer die anderen 2 GB für den Quellcode behalte . Ich möchte nicht das Risiko eingehen, dass es getauscht wird, denn das ist ärgerlich.
JaredC

Swappiness ist systemweit. In der Tat, wenn Sie etwas anderes tun und Ihre Dateien aus dem Speicher entladen werden, müssen Sie sie nur mit der zweiten Zeile neu laden. Wenn der Speicher für etwas anderes freigegeben werden muss, möchten Sie das Risiko nicht wirklich eingehen, um es durch Tausch zu erledigen. Übrigens, tmpfsim gleichen Fall würde auch weg getauscht werden.
Shellholic

2
Persönlich fiel mir ein hoher Swappiness auf Workstations aboslutely schrecklich. Obwohl einige Funktionen durch den größeren Cache (dh mehr zwischengespeicherte Dateien) möglicherweise beschleunigt werden, hat dies einen Preis: Sie zahlen dafür, wenn Sie zwischen Programmen wechseln, was die Benutzer bei der Arbeit an einem System als Erstes bemerken. Wenn ich von einem Browser in ein Büro zu einem anderen Browser in eine E-Mail wechsle, muss ich einfach 1-2 Sekunden warten, bis jedes Programm wieder eingewechselt ist. Auf allen meinen Linux-Rechnern habe ich swappiness im Allgemeinen auf einen niedrigen Wert von 10 gesetzt.
fgysin setzt Monica

6

Das Erzwingen des Cache ist nicht der richtige Weg. Es ist besser, die Quellen auf der Festplatte zu belassen und sie auf tmpfs zu kompilieren. Viele Build-Systeme wie qmake und CMake unterstützen Out-of-Source-Builds.


6

Der inosyncDaemon scheint genau das zu tun, was Sie wollen, wenn Sie mit einer Ramdisk rsynchen wollen. Anstatt etwa alle 10 Sekunden eine Synchronisierung durchzuführen, wird die inotify-Funktion von Linux verwendet, um eine Synchronisierung durchzuführen, wenn sich eine Datei ändert. Ich habe es im Debian-Repository als inosyncPaket gefunden oder seine Quelle ist unter http://bb.xnull.de/projects/inosync/ verfügbar .


Das hört sich ganz nützlich an. Ich werde es untersuchen und berichten. Vielen Dank!
JaredC

5

Dieses Ding scheint für mich zu funktionieren, wenn ich bestimmte Dateien oder alle Dateien in einem bestimmten Verzeichnis im Cache behalten möchte.

vmtouch scheint genau das Richtige zu tun. In Beispiel 5 könnte es das geben, was Sie brauchen.

vmtouch -dl /whatever/directory/

Ich musste es als root mit ausführen sudo


1
Es werden keine neuen / entfernten Dateien angezeigt.
Vi.

3

Bei ausreichendem Arbeitsspeicher führt Ihr Build auf der Ramdisk keine E / A aus. Dies kann alles beschleunigen, was Dateien liest oder schreibt. I / O ist eine der langsamsten Operationen. Selbst wenn Sie alles vor dem Build zwischengespeichert bekommen, haben Sie immer noch die I / Os zum Schreiben, obwohl sie nur minimale Auswirkungen haben sollten.

Sie können eine gewisse Beschleunigung erzielen, indem Sie alle Dateien vorab in den Cache laden. Die dafür erforderliche Zeit sollte jedoch in die Gesamtaufbauzeit einbezogen werden. Dies bringt Ihnen möglicherweise keinen großen Vorteil.

Erstellen Sie das Objekt und die Zwischendateien im RAM anstatt auf der Festplatte. Wenn Sie inkrementelle Builds ausführen, können Sie bei häufigen Builds erhebliche Vorteile erzielen. Bei den meisten Projekten mache ich täglich einen Clean Build und dazwischen inkrementelle Builds. Integrationsbuilds sind immer reine Builds, aber ich versuche, sie auf weniger als einen pro Tag zu beschränken.

Sie können eine gewisse Leistung erzielen, indem Sie eine ext2-Partition verwenden, bei der atime deaktiviert ist. Ihre Quelle sollte sich in der Versionskontrolle eines Journaled File Systems wie ext3 / 4 befinden.


2

Wie bereits erwähnt, besteht die naheliegende Möglichkeit darin, die gesamte Verzeichnisstruktur und den gesamten Dateiinhalt der Daten zu lesen, die zwischengespeichert werden sollen.

Sie können dies automatisieren, indem Sie ein Skript schreiben, um die Ausgabe zu überwachen vmstat 1(verwenden Sie ein gleichwertiges Tool für Ihr Betriebssystem) und eine Summe der Anzahl der geschriebenen und gelesenen Blöcke zu erhalten. Wenn die Summe einen von Ihnen festgelegten Schwellenwert überschreitet, lesen Sie alle Dateien, die Sie zwischenspeichern möchten, setzen Sie die Summe zurück und überwachen Sie anschließend die vmstat-Ausgabe. Zum schnellen Lesen von Dateien: Wenn Ihr Baum viele Dateien enthält, vermeiden Sie find ... -exec catstattdessen find ... -print0 | xargs -0 catein benutzerdefiniertes Programm oder versuchen Sie es , das cat nicht für jede Datei ausführt.

Das Überwachen der Festplatten-E / A ist der Verwendung eines festen Intervalls vorzuziehen, da dies signalisiert, dass Ihre Daten abhängig von der Festplatten-E / A-Last mehr oder weniger häufig neu gelesen werden müssen.

Ich habe diese automatisierte Methode erfolgreich auf Systemen verwendet, auf denen einige Indexdatei-Lesevorgänge erforderlich waren, um immer schnell zu sein und Festplatten-E / A zu vermeiden. Ich habe strace auch verwendet, um eine Liste aller Dateien zu erstellen, auf die beim Anmelden zugegriffen wird, damit ich für schnelle Anmeldungen alles im Cache behalten kann.

Das ist vielleicht nicht die bestmögliche Lösung, aber es hat mir gut gefallen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.