Sort --parallel ist nicht parallelisierend

3463
Jeremy Kemball

Ich versuche, einen Satz von Zeilen, die mit egrep mit sort -u aus einer Datei gezogen wurden, eindeutig zu machen und sie dann zu zählen. Etwa 10% der Zeilen (alle 100 Zeichen des Alphabets [ATCG]) sind doppelt vorhanden. Es gibt zwei Dateien, jeweils etwa 3 Gigs, 50% sind nicht relevant, also vielleicht 300 Millionen Zeilen.

LC_ALL=C grep -E <files> | sort --parallel=24 -u | wc -m 

Zwischen LC_ALL = C und der Verwendung von -x zur Beschleunigung von grep ist die Sortierung bei weitem der langsamste Teil. Das Lesen der Manpages führte mich zu --parallel = n, aber das Experimentieren zeigte absolut keine Verbesserung. Ein wenig Graben mit top zeigte, dass auch bei --parallel = 24 der Sortiervorgang immer nur auf einem Prozessor läuft.

Ich habe 4 Chips mit 6 Kernen und 2 Threads / Kern, was insgesamt 48 logische Prozessoren ergibt. Siehe lscpu, da / proc / cpuinfo zu lang wäre.

Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit Byte Order: Little Endian CPU(s): 48 On-line CPU(s) list: 0-47 Thread(s) per core: 2 Core(s) per socket: 6 Socket(s): 4 NUMA node(s): 8 Vendor ID: AuthenticAMD CPU family: 21 Model: 1 Stepping: 2 CPU MHz: 1400.000 BogoMIPS: 5199.96 

Was vermisse ich? Kann ich die Parallelverarbeitung auch dann nicht sehen, wenn der Prozess IO-gebunden ist? Der Sortierprozess verbraucht 99% des Prozessors, auf dem er sich gerade befindet, also sollte ich in der Lage sein, Parallelisierung zu sehen, falls dies geschieht. Speicher ist kein Problem, ich habe 256 GB zum Spielen und nichts davon wird von irgendetwas anderem verwendet.

Etwas, das ich entdeckte, als ich grep zu einer Datei leitete, dann las ich die Datei mit sort:

 LC_ALL=C grep -E <files> > reads.txt ; sort reads.txt -u | wc -m  default, file 1m 50s --parallel=24, file 1m15s --parallel=48, file 1m6s --parallel=1, no file 10m53s --parallel=2, no file 10m42s --parallel=4 no file 10m56s  others still running 

Bei diesen Benchmarks ist es ziemlich klar, dass bei der Art der übergebenen Eingabe überhaupt keine Parallelisierung erfolgt. Wenn eine Datei gelesen werden darf, wird die Last wie angewiesen aufgeteilt.

8
Welche Art ist das auf welcher Distribution? Die standardmäßige Sortierung kennt diese Option nicht. ott-- vor 9 Jahren 0
"uname -a" gibt "3.13.0-46-generic # 79-Ubuntu SMP" an und "lsb_release -a" gibt den 14.04.2-Codenamen als vertrauenswürdig an, und die Version von sort, die Teil von gnu coreutils ist, entsprechend "man sort" `. Jeremy Kemball vor 9 Jahren 0
Es scheint mir, dass es Teile gibt, die noch einmal gelesen werden müssen: https://www.gnu.org/software/coreutils/manual/html_node/sort-invocation.html Hannu vor 9 Jahren 0
Ich bin mir nicht sicher, was ich bei @Hannu verstehe. Könnten Sie etwas genauer sein? sort --parallel = 2 parallelisiert auch nicht. 4 oder 8 auch nicht. Nproc gibt 48 zurück, wie es sollte. Jeremy Kemball vor 9 Jahren 0
Ich würde sagen ... verwende dafür keine coreutils. * Amüsant * wir hatten eine sehr ähnliche Frage und gut ... jede andere Methode funktioniert besser http://superuser.com/a/485987/10165 Journeyman Geek vor 9 Jahren 1
@JeremyKemball - die Tatsache, dass n> 8 für Anfänger nicht viel beitragen würde, schien mir auch, dass Ihre Verwendung von -u (unique) nicht mit dem übereinstimmt, wonach Sie gefragt haben; Verwenden Sie "unique" besser als "sort -u" Hannu vor 9 Jahren 0
`sort | uniq und und sort -u sind explizit gleichwertig, wenn Sie die Zeilen nicht mit Schlüsseln sortieren. Gibt es einen Grund, eine zusätzliche Leitung zu verwenden? Jeremy Kemball vor 9 Jahren 0
Wie ich den Text unter dem obigen Link verstehe, gibt es einen Unterschied. Aber dann bin ich kein englischer Muttersprachler. Hannu vor 9 Jahren 0
Sie unterscheiden sich im Vergleich zum letzten Ort, wenn Sie die angegebenen Sortier- / Sortieroptionen verwenden, sodass Dinge, die identisch sortiert werden, durch diese Sortieroptionen eindeutig sind. Ich habe -d, -f, -n, -h, -M, -v oder -k nicht, also `sort | uniq` ist explizit identisch mit `sort --unique`, doppelt so, da ich sehr langweilige Saiten habe. Jeremy Kemball vor 9 Jahren 0

1 Antwort auf die Frage

18
pixelbeat

sort erstellt keinen Thread, wenn es nicht nötig ist, und für kleine Dateien ist es einfach zu viel Aufwand. Leider behandelt die Sortierung eine Pipe wie eine kleine Datei. Wenn Sie genug Daten an 24 Threads weitergeben möchten, müssen Sie angeben, dass ein großer interner Puffer verwendet werden soll (beim Sortieren mit großen Dateien erfolgt die Sortierung automatisch). Dies sollten wir im Vorfeld (zumindest in der Dokumentation) verbessern. Sie wollen also etwas wie:

(export LC_ALL=C; grep -E <files> | sort -S1G --parallel=24 -u | wc -m) 

Hinweis: Ich habe für alle Prozesse LC_ALL = C festgelegt, da alle von diesen Daten profitieren werden.

Übrigens können Sie die Sortier-Threads mit etwas überwachen:

watch -n.1 ps -C sort -L -o pcpu