Sortieren - parallel ist nicht parallelisierend

10

Ich versuche, eine Reihe 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 dupliziert. Es gibt zwei Dateien, jeweils ca. 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 der mit Abstand langsamste Teil die Sortierung. Das Lesen der Manpages führte mich zu --parallel = n, aber das Experimentieren zeigte absolut keine Verbesserung. Ein wenig Graben mit oben zeigte, dass selbst mit --parallel = 24 der Sortiervorgang immer nur auf einem Prozessor gleichzeitig ausgeführt wird.

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? Sollte ich nicht trotzdem eine parallele Verarbeitung sehen, auch wenn der Prozess an E / A gebunden ist? Der Sortierprozess verwendet 99% des Prozessors, auf dem er sich zu einem bestimmten Zeitpunkt tatsächlich befindet. Daher sollte ich in der Lage sein, Parallelisierung zu erkennen, wenn dies geschieht. Speicher ist kein Problem, ich habe 256 GB zum Spielen und nichts davon wird von irgendetwas anderem verwendet.

Etwas, das ich entdeckt habe, als ich grep zu einer Datei geleitet habe und dann die Datei mit sort gelesen habe:

 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 die Sortierung von Piped-Eingaben überhaupt nicht parallelisiert. Wenn eine Dateisortierung gelesen werden darf, wird die Last wie angewiesen aufgeteilt.

Jeremy Kemball
quelle
Was sortist das auf welcher Distribution? Der Standard sortkennt diese Option nicht.
ott--
uname -agibt "3.13.0-46-generic # 79-Ubuntu SMP" und lsb_release -abehauptet 14.04.2 Codename vertrauenswürdig, und die Version der Sorte, die Teil der Gnu Coreutils ist, laut man sort.
Jeremy Kemball
Es scheint mir, dass es hier Teile gibt, die noch einmal gelesen werden müssen: gnu.org/software/coreutils/manual/html_node/…
Hannu
Ich bin mir nicht sicher, ob ich verstehe, was Sie bei @Hannu bekommen. Könnten Sie genauer sein? sort --parallel = 2 parallelisiert auch nicht. Weder 4 noch 8. nproc gibt 48 zurück, wie es sollte.
Jeremy Kemball
1
Ich würde sagen ... benutze dafür keine Coreutils. Amüsanterweise hatten wir eine sehr ähnliche Frage und nun ... jede andere Methode funktioniert besser superuser.com/a/485987/10165
Journeyman Geek

Antworten:

24

sort erstellt keinen Thread, es sei denn, dies ist erforderlich, und für kleine Dateien ist der Aufwand einfach zu hoch. Jetzt behandelt sort leider eine Pipe wie eine kleine Datei. Wenn Sie 24 Threads mit genügend Daten versorgen möchten, müssen Sie angeben, dass sortiert werden soll, um einen großen internen Puffer zu verwenden (sortiert dies automatisch, wenn große Dateien angezeigt werden). Dies sollten wir im Upstream verbessern (zumindest in der Dokumentation). Sie möchten also etwas wie:

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

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

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

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