Ich xargs
rufe ein Python-Skript auf, um ungefähr 30 Millionen kleine Dateien zu verarbeiten. Ich hoffe, xargs
den Prozess parallelisieren zu können. Der Befehl, den ich benutze, ist:
find ./data -name "*.json" -print0 |
xargs -0 -I{} -P 40 python Convert.py {} > log.txt
Grundsätzlich Convert.py
wird in einem kleinen lesen json - Datei (4kb), einige Verarbeitung und Schreiben auf eine andere 4kb Datei. Ich laufe auf einem Server mit 40 CPU-Kernen. Auf diesem Server wird kein anderer CPU-intensiver Prozess ausgeführt.
Durch die Überwachung von htop (gibt es übrigens eine andere gute Möglichkeit, die CPU-Leistung zu überwachen?) Finde ich, dass dies -P 40
nicht so schnell ist wie erwartet. Manchmal frieren alle Kerne ein und fallen 3-4 Sekunden lang fast auf Null ab, dann erholen sie sich auf 60-70%. Dann versuche ich, die Anzahl der parallelen Prozesse zu verringern -P 20-30
, aber es ist immer noch nicht sehr schnell. Das ideale Verhalten sollte eine lineare Beschleunigung sein. Irgendwelche Vorschläge für die parallele Verwendung von xargs?
quelle
xargs -P
und>
öffnet sich für Rennbedingungen aufgrund des Halblinienproblems gnu.org/software/parallel/… Die Verwendung von GNU Parallel wird dieses Problem nicht haben.Antworten:
Ich würde wetten, dass Ihr Problem Python ist . Sie haben nicht angegeben, welche Art von Verarbeitung für jede Datei ausgeführt wird, aber vorausgesetzt, Sie verarbeiten nur die Daten im Speicher, wird die Laufzeit durch das Starten von 30 Millionen virtuellen Python-Maschinen (Interpreten) dominiert.
Wenn Sie Ihr Python-Programm so umstrukturieren können, dass statt nur einer eine Liste von Dateien erstellt wird, wird die Leistung erheblich verbessert. Sie können dann weiterhin xargs verwenden, um die Leistung weiter zu verbessern. Zum Beispiel 40 Prozesse, von denen jeder 1000 Dateien verarbeitet:
Das soll nicht heißen, dass Python eine schlechte / langsame Sprache ist; Es ist einfach nicht für die Startzeit optimiert. Sie sehen dies bei jeder auf virtuellen Maschinen basierenden oder interpretierten Sprache. Java wäre zum Beispiel noch schlimmer. Wenn Ihr Programm in C geschrieben wäre, würde es immer noch kosten, einen separaten Betriebssystemprozess zu starten, um jede Datei zu verarbeiten, aber es wäre viel weniger.
Von dort aus können Sie herumspielen, um
-P
zu sehen, ob Sie etwas mehr Geschwindigkeit herausholen können, indem Sie möglicherweise die Anzahl der Prozesse erhöhen, um die Vorteile von Prozessoren im Leerlauf zu nutzen, während Daten gelesen / geschrieben werden.quelle
Betrachten Sie also zunächst die Einschränkungen:
Was ist die Einschränkung für jeden Job? Wenn es sich um E / A handelt, können Sie wahrscheinlich mit mehreren Jobs pro CPU-Kern davonkommen, bis Sie das E / A-Limit erreicht haben. Wenn es jedoch CPU-intensiv ist, ist es schlimmer, als sinnlos mehr Jobs gleichzeitig auszuführen, als Sie über CPU-Kerne verfügen.
Mein Verständnis dieser Dinge ist, dass GNU Parallel Ihnen eine bessere Kontrolle über die Warteschlange von Jobs usw. geben würde.
Siehe GNU parallel vs & (ich meine Hintergrund) vs xargs -P für eine detailliertere Erklärung, wie sich die beiden unterscheiden.
quelle
Überprüfen Sie, wie andere sagten, ob Sie I / O-gebunden sind. Auch xargs' man - Seite schlägt mit
-n
mit-P
, Sie erwähnen nicht die Anzahl derConvert.py
Prozesse , die Sie parallel sehen zu laufen.Wenn Sie an E / A gebunden sind, können Sie versuchen, ein SSD-Blockgerät zu verwenden oder die Verarbeitung in einem tmpfs durchzuführen (in diesem Fall sollten Sie natürlich nach genügend Speicher suchen, um einen Austausch aufgrund von tmpfs zu vermeiden Druck (glaube ich) und der Aufwand, die Daten überhaupt erst zu kopieren).
quelle