Beim Schreiben laufen A | B
beide Prozesse bereits parallel. Wenn Sie davon ausgehen, dass sie nur einen Kern verwenden, liegt dies wahrscheinlich an den CPU-Affinitätseinstellungen (möglicherweise gibt es ein Tool, um einen Prozess mit unterschiedlicher Affinität zu erzeugen) oder daran, dass ein Prozess nicht ausreicht, um einen ganzen Kern und das System zu halten. " zieht es vor, "das Computing nicht zu verbreiten".
Um mehrere B's mit einem A zu betreiben, benötigen Sie ein Tool wie split
mit der --filter
Option:
A | split [OPTIONS] --filter="B"
Dies kann jedoch die Zeilenreihenfolge in der Ausgabe durcheinander bringen, da die B-Jobs nicht alle mit der gleichen Geschwindigkeit ausgeführt werden. Wenn dies ein Problem ist, müssen Sie möglicherweise die B i-te Ausgabe in eine Zwischendatei umleiten und diese am Ende mit zusammenfügen cat
. Dies kann wiederum einen beträchtlichen Speicherplatz erfordern.
Es gibt andere Optionen (z. B. können Sie jede Instanz von B auf eine einzelne zeilengepufferte Ausgabe beschränken, warten, bis eine ganze "Runde" von Bs beendet ist, das Äquivalent einer Reduction- to split
- Map ausführen und cat
die temporäre Ausgabe zusammen ausführen ). mit unterschiedlichen Wirkungsgraden. Die soeben beschriebene Option 'round' wartet darauf, dass die langsamste Instanz von B beendet wird. Sie hängt daher stark von der verfügbaren Pufferung für B ab. [m]buffer
kann helfen oder auch nicht, je nachdem, welche Operationen durchgeführt werden.
Beispiele
Generieren Sie die ersten 1000 Zahlen und zählen Sie die Zeilen parallel:
seq 1 1000 | split -n r/10 -u --filter="wc -l"
100
100
100
100
100
100
100
100
100
100
Wenn wir die Zeilen "markieren" würden, würden wir sehen, dass jede erste Zeile an Prozess 1 gesendet wird, jede fünfte Zeile an Prozess 5 und so weiter. Darüber hinaus ist split
der erste Prozess in der Zeit, die zum Starten des zweiten Prozesses benötigt wird, bereits ein guter Weg, um sein Kontingent zu erhöhen:
seq 1 1000 | split -n r/10 -u --filter="sed -e 's/^/$RANDOM - /g'" | head -n 10
19190 - 1
19190 - 11
19190 - 21
19190 - 31
19190 - 41
19190 - 51
19190 - 61
19190 - 71
19190 - 81
Bei der Ausführung auf einem 2-Kern - Maschine seq
, split
und die wc
Prozesse teilen sich die Kerne; Bei näherer Betrachtung belässt das System die ersten beiden Prozesse auf CPU0 und teilt CPU1 unter den Arbeitsprozessen auf:
%Cpu0 : 47.2 us, 13.7 sy, 0.0 ni, 38.1 id, 1.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu1 : 15.8 us, 82.9 sy, 0.0 ni, 1.0 id, 0.0 wa, 0.3 hi, 0.0 si, 0.0 st
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
5314 lserni 20 0 4516 568 476 R 23.9 0.0 0:03.30 seq
5315 lserni 20 0 4580 720 608 R 52.5 0.0 0:07.32 split
5317 lserni 20 0 4520 576 484 S 13.3 0.0 0:01.86 wc
5318 lserni 20 0 4520 572 484 S 14.0 0.0 0:01.88 wc
5319 lserni 20 0 4520 576 484 S 13.6 0.0 0:01.88 wc
5320 lserni 20 0 4520 576 484 S 13.3 0.0 0:01.85 wc
5321 lserni 20 0 4520 572 484 S 13.3 0.0 0:01.84 wc
5322 lserni 20 0 4520 576 484 S 13.3 0.0 0:01.86 wc
5323 lserni 20 0 4520 576 484 S 13.3 0.0 0:01.86 wc
5324 lserni 20 0 4520 576 484 S 13.3 0.0 0:01.87 wc
Beachten Sie, dass besonders split
viel CPU verbraucht wird. Dies wird proportional zu den Bedürfnissen von A abnehmen. dh wenn A ein schwererer Prozess ist als seq
, split
verringert sich der relative Overhead von . Aber wenn A ein sehr leichter Prozess ist und B ziemlich schnell ist (so dass Sie nicht mehr als 2-3 Bs benötigen, um mit A mitzuhalten), lohnt es sich möglicherweise nicht, mit split
(oder allgemein mit Pipes) zu parallelisieren .
A | B | C
wie in separaten Prozessen parallel ist, kann es aufgrund der Art der Pipes (B muss auf die Ausgabe von A warten, C muss auf die Ausgabe von B warten) in einigen Fällen immer noch linear sein. Es kommt ganz darauf an, welche Art von Output sie produzieren. Es gibt nicht viele Fälle, in denen das Ausführen von mehrerenB
sehr hilfreich ist. Es ist durchaus möglich, dass das parallele wc-Beispiel langsamer alswc
normal ist, da das Aufteilen mehr Ressourcen beansprucht als das normale Zählen von Zeilen. Mit Vorsicht anwenden.