Kiedy piszesz A | B
, oba procesy działają już równolegle. Jeśli widzisz, że używają tylko jednego rdzenia, prawdopodobnie wynika to z jednego z ustawień koligacji procesora (być może istnieje jakieś narzędzie do odrodzenia procesu o innym powinowactwie) lub dlatego, że jeden proces nie wystarcza do utrzymania całego rdzenia, a system „ woli „nie rozpowszechniać informatyki.
Aby uruchomić kilka B z jednym A, potrzebujesz narzędzia takiego jak split
z --filter
opcją:
A | split [OPTIONS] --filter="B"
Może to jednak popsuć kolejność linii na wyjściu, ponieważ zadania B nie będą działały z tą samą prędkością. Jeśli jest to problem, może być konieczne przekierowanie wyjścia B i-tego do pliku pośredniego i połączenie ich na końcu za pomocą cat
. To z kolei może wymagać znacznego miejsca na dysku.
Istnieją inne opcje (np można ograniczyć każdą instancję B do jednego wyjścia liniowego buforowane, poczekaj, aż cała „okrągły” z B zakończy, uruchom odpowiednik zmniejszyć do split
„s mapę i cat
wyjście tymczasowe razem), o różnym poziomie wydajności. Opisana na przykład opcja „round” będzie czekać na zakończenie najwolniejszej instancji B , więc będzie w dużym stopniu zależna od dostępnego buforowania dla B; [m]buffer
może pomóc lub nie, w zależności od operacji.
Przykłady
Wygeneruj pierwsze 1000 liczb i policz linie równolegle:
seq 1 1000 | split -n r/10 -u --filter="wc -l"
100
100
100
100
100
100
100
100
100
100
Gdybyśmy „oznaczyli” linie, zobaczylibyśmy, że każda pierwsza linia jest wysyłana do przetwarzania nr 1, każda piąta linia do przetwarzania nr 5 i tak dalej. Co więcej, w czasie potrzebnym split
na odrodzenie drugiego procesu, pierwszy jest już dobrym sposobem na przydzielenie limitu:
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
Podczas wykonywania na maszynie 2-rdzeniowej seq
, split
a wc
procesy współużytkują rdzenie; ale patrząc bliżej, system pozostawia pierwsze dwa procesy na CPU0 i dzieli CPU1 na procesy robocze:
%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
Zwróć uwagę, że split
zjada znaczną ilość procesora. Zmniejszy się proporcjonalnie do potrzeb A; tj. jeśli A jest procesem cięższym niż seq
, względny narzut split
zmniejszy się. Ale jeśli A jest bardzo lekkim procesem, a B jest dość szybki (tak że nie potrzebujesz więcej niż 2-3 B, aby zachować zgodność z A), wówczas równoległe stosowanie split
(lub ogólnie rur) może nie być tego warte.
A | B | C
jest równoległy, jak w oddzielnych procesach, ze względu na charakter rur (B musi czekać na wyjście A, C musi czekać na wyjście B), w niektórych przypadkach może być liniowy. Zależy to całkowicie od rodzaju produkcji, jaką wytwarzają. Nie ma wielu przypadków, w których uruchomienie wieluB
pomógłoby bardzo, jest całkiem możliwe, że przykład równoległego wc jest wolniejszy niż normalny,wc
ponieważ dzielenie może zająć więcej zasobów niż normalne liczenie linii. Używaj ostrożnie.