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