Lorsque vous écrivez A | B
, les deux processus s'exécutent déjà en parallèle. Si vous les voyez comme n'utilisant qu'un seul cœur, c'est probablement à cause des paramètres d'affinité du processeur (peut-être qu'il existe un outil pour générer un processus avec une affinité différente) ou parce qu'un processus ne suffit pas pour contenir un cœur entier et le système " préfère "ne pas étendre l'informatique.
Pour exécuter plusieurs B avec un A, vous avez besoin d'un outil tel que split
l' --filter
option:
A | split [OPTIONS] --filter="B"
Cependant, cela risque de perturber l'ordre des lignes dans la sortie, car les travaux B ne s'exécuteront pas tous à la même vitesse. S'il s'agit d'un problème, vous devrez peut-être rediriger la sortie B i-ème vers un fichier intermédiaire et les assembler à la fin à l'aide de cat
. Ceci, à son tour, peut nécessiter un espace disque considérable.
D' autres options existent (par exemple , vous pouvez limiter chaque instance de B à une seule sortie en mémoire tampon ligne, attendez jusqu'à ce qu'un tout « rond » de B est terminée, lancez l'équivalent d'une réduire à split
« s carte , et cat
la sortie temporaire ensemble), avec différents niveaux d'efficacité. L'option 'round' qui vient d'être décrite, par exemple, attendra la fin de l' instance la plus lente de B , elle dépendra donc grandement de la mise en mémoire tampon disponible pour B; [m]buffer
pourrait aider, ou non, selon les opérations.
Exemples
Générez les 1000 premiers nombres et comptez les lignes en parallèle:
seq 1 1000 | split -n r/10 -u --filter="wc -l"
100
100
100
100
100
100
100
100
100
100
Si nous devions "marquer" les lignes, nous verrions que chaque première ligne est envoyée au processus # 1, chaque cinquième ligne au processus # 5 et ainsi de suite. De plus, dans le temps qu'il faut split
pour engendrer le second processus, le premier est déjà un bon chemin dans son quota:
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
Lors de l'exécution sur une machine à 2 cœurs seq
, split
et les wc
processus partagent les cœurs; mais en y regardant de plus près, le système laisse les deux premiers processus sur CPU0 et divise CPU1 entre les processus de travail:
%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
Notez surtout que split
consomme une quantité considérable de CPU. Cela diminuera proportionnellement aux besoins de A; c'est-à-dire que si A est un processus plus lourd que seq
, la surcharge relative de split
diminuera. Mais si A est un processus très léger et B est assez rapide (de sorte que vous n'avez pas besoin de plus de 2-3 B pour rester avec A), la parallélisation avec split
(ou les tuyaux en général) pourrait ne pas en valoir la peine.
A | B | C
soit parallèle comme dans des processus séparés, en raison de la nature des tuyaux (B doit attendre la sortie de A, C doit attendre la sortie de B), il peut toujours être linéaire dans certains cas. Cela dépend entièrement du type de sortie qu'ils produisent. Il n'y a pas beaucoup de cas où l'exécution multipleB
aiderait beaucoup, il est tout à fait possible que l'exemple de wc parallèle soit plus lent que normalwc
car le fractionnement peut prendre plus de ressources que de compter les lignes normalement. Utilisez avec précaution.