Коли ви пишете A | B
, обидва процеси вже працюють паралельно. Якщо ви бачите, що вони використовують лише одне ядро, це, мабуть, через налаштування спорідненості процесора (можливо, є якийсь інструмент для нерестування процесу з різною спорідненістю) або тому, що одного процесу недостатньо, щоб вмістити все ядро та систему " вважає за краще "не поширювати обчислення.
Для запуску декількох B з одним A, вам потрібен такий інструмент, як split
з --filter
опцією:
A | split [OPTIONS] --filter="B"
Це, однак, може зіпсувати порядок рядків на виході, оскільки завдання B не працюватимуть з однаковою швидкістю. Якщо це проблема, можливо, вам доведеться перенаправити B i-й вихід на проміжний файл і з’єднати їх разом в кінці, використовуючи cat
. Це, у свою чергу, може зажадати значного місця на диску.
Існують і інші варіанти (наприклад, ви можете обмежити кожен екземпляр B лише одним вихідним рядком, зачекайте, поки закінчиться цілий "раунд" B, запустіть еквівалент зменшення до split
S » карт , а також cat
тимчасовий вихід разом), з різним рівнем ефективності. Описаний, наприклад, "круглий" варіант буде чекати, коли закінчиться найповільніший екземпляр 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
Під час виконання на двоядерній машині 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
зменшиться. Але якщо А це дуже легкий процес і B досить швидко (так , що вам потрібно не більше 2-3 Б, щоб тримати разом з А), то розпаралелювання з split
(або труби в цілому) може бути і не варто.
A | B | C
паралельно, як і в окремих процесах, через характер труб (B доводиться чекати виходу A, C повинен чекати виходу B), в деяких випадках він все ще може бути лінійним. Це повністю залежить від того, який вид продукції вони виробляють. Не так багато випадків, коли запуск декількохB
допоможе багато, цілком можливо, що приклад паралельного wc повільніше, ніж регулярний,wc
оскільки розщеплення може зайняти більше ресурсів, ніж підрахунок рядків. Використовуйте обережно.