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 rsync
alle 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 rsync
ist blitzschnell, aber würde das wirklich funktionieren? Sicher könnte das Betriebssystem besser sein ...
quelle
time
Ihre Zusammenstellung und das Ergebnis mit uns teilen? Es würde einige Kontroversen zerstreuen.make clean && /usr/bin/time -v make
(Verwenden Sie nicht den eingebautentime
Befehl bash )time
eingebaute 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, ...Antworten:
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.
noatime
Mount-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.sync()
oder weil der Kernel häufig seine Ausgabepuffer leert, dauert das Schreiben auf eine Festplatte länger als auf tmpfs.quelle
Linux verwendet standardmäßig den RAM als Festplatten-Cache. Versuchen Sie zur Demonstration,
time find /some/dir/containing/a/lot/of/files > /dev/null
zwei 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:
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.
quelle
tmpfs
im gleichen Fall würde auch weg getauscht werden.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.
quelle
Der
inosync
Daemon 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 alsinosync
Paket gefunden oder seine Quelle ist unter http://bb.xnull.de/projects/inosync/ verfügbar .quelle
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.
Ich musste es als root mit ausführen
sudo
quelle
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.
quelle
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 Siefind ... -exec cat
stattdessenfind ... -print0 | xargs -0 cat
ein 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.
quelle