Когда вы пишете A | B
, оба процесса уже работают параллельно. Если вы видите, что они используют только одно ядро, это может быть связано либо с настройками привязки к процессору (возможно, есть какой-то инструмент для запуска процесса с другой привязкой), либо потому, что одного процесса недостаточно для хранения всего ядра и системы ». Предпочитает «не распространять вычисления».
Чтобы запустить несколько B с одним A, вам нужен инструмент, например, split
с --filter
опцией:
A | split [OPTIONS] --filter="B"
Это, однако, может испортить порядок строк в выходных данных, поскольку задания B не будут выполняться с одинаковой скоростью. Если это проблема, вам может понадобиться перенаправить вывод i-го файла в промежуточный файл и сшить их вместе в конце, используяcat
. Это, в свою очередь, может потребовать значительного дискового пространства.
Существуют и другие параметры (например , вы могли бы ограничить каждый экземпляр B к одной линии буферизации вывода, ждать , пока весь «круглый» из Б закончила, не запустить эквивалент уменьшить до split
S» карт , а также cat
временный выход вместе), с различными уровнями эффективности. Опция 'round', например, только что описанная, будет ожидать завершения самого медленного экземпляра B , поэтому она будет сильно зависеть от доступной буферизации для B; [m]buffer
может помочь, а может и нет, в зависимости от операций.
Примеры
Сгенерируйте первые 1000 чисел и сосчитайте линии параллельно:
seq 1 1000 | split -n r/10 -u --filter="wc -l"
100
100
100
100
100
100
100
100
100
100
Если бы мы «пометили» строки, мы бы увидели, что каждая первая строка отправляется в процесс № 1, каждая пятая строка - в процесс № 5 и так далее. Более того, за то время, которое требуется split
для запуска второго процесса, первый уже является хорошим способом в его квоте:
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
При выполнении на 2-жильную машине, seq
, split
и wc
процессы совместно сердечник; но при ближайшем рассмотрении система оставляет первые два процесса на CPU0 и делит CPU1 между рабочими процессами:
%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
Особенно обратите внимание, что split
кушает значительное количество процессоров. Это будет уменьшаться пропорционально потребностям А; то есть, если A более тяжелый процесс, чем seq
, относительные накладные расходы split
уменьшатся. Но если A - очень легкий процесс, а B - довольно быстрый (так что вам нужно не больше, чем 2-3 B, чтобы держаться вместе с A), то распараллеливание с split
(или трубами в целом) может не стоить этого.
A | B | C
параллельно , как в отдельных процессах, в связи с характером труб (В должен ждать выхода A, C должен ждать выхода B) он все еще может быть линейным , в некоторых случаях. Это полностью зависит от того, какую продукцию они производят. Существует не так много случаев, когда многократный запускB
мог бы сильно помочь, вполне возможно, что пример параллельного wc медленнее обычного,wc
поскольку для расщепления может потребоваться больше ресурсов, чем для обычного подсчета строк. Используйте с осторожностью.