Выполнение переданных по каналу команд параллельно

Хорошо, наконец понятый это.

команда pvscan обеспечивает отображение, которое я ищу.

16
12.09.2017, 12:35
2 ответа

Проблема с split --filter это, вывод может быть перепутан, таким образом, Вы получаете половину строки от процесса 1 сопровождаемый наполовину строка от процесса 2.

Параллель GNU гарантирует, что не будет никакой путаницы.

Поэтому предположите, что Вы хотите сделать:

 A | B | C

Но это, B является ужасно медленным, и таким образом Вы хотите параллелизировать это. Затем можно сделать:

A | parallel --pipe B | C

Параллель GNU разделениями по умолчанию на \n и размере блока 1 МБ. Это может быть скорректировано с - недавний и - блок.

Можно найти больше о Параллели GNU в: http://www.gnu.org/s/parallel/

Можно установить Параллель GNU всего за 10 секунд с:

wget -O - pi.dk/3 | sh 

Посмотрите вводное видео на http://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

14
27.01.2020, 19:48
  • 1
    В то время как я категорически не согласен относительно метода установки :-), +1, потому что Ваше решение решает большинство проблем с моим. –  LSerni 15.06.2013, 15:46
  • 2
    Этот хорош действительно. У Вас также есть какие-либо предложения для параметров, которые будут использоваться? Я знаю, что программа A произведет больше чем 1 ТБ данных приблизительно 5 ГБ в минуту. Программа B обрабатывает данные в 5 раз медленнее, чем выводы это, и у меня есть 5 ядер в моем распоряжении для этой задачи. –  Jernej 15.06.2013, 15:50
  • 3
    GNU в настоящее время может в большей части дескриптора приблизительно 100 МБ/с, таким образом, Вы собираетесь коснуться того предела. Оптимальное --block-size будет зависеть от суммы RAM и как быстро можно запустить новое B. В Вашей ситуации я использовал бы --block 100M и посмотрите, как это работало. –  Ole Tange 15.06.2013, 16:11
  • 4
    @lserni можно ли придумать метод установки, который лучше, который работает над большинством машин UNIX и требует подобного объема работы от пользователя? –  Ole Tange 15.06.2013, 16:15
  • 5
    Извините, я не ясно выражался. Метод установки - сценарий передал sh - является большим. Проблема заключается мимоходом он к sh: загрузка и выполнение исполняемого кода от сайта. Обратите внимание, возможно, я просто слишком параноик, так как можно было возразить, что изготовленный на заказ об/мин или DEB являются в основном тем же самым, и даже регистрация кода на странице, которая будет скопирована и вставлена, привела бы к людям, делающим так вслепую так или иначе. –  LSerni 15.06.2013, 16:43

Когда Вы пишете A | B, оба процесса уже выполняются параллельно. Если Вы рассматриваете их как использование только одного ядра, это, вероятно, потому что любая из настроек привязки ЦП (возможно, существует некоторый инструмент для порождения процесса с другой привязкой) или потому что одного процесса не достаточно для содержания целого ядра и системы, "предпочитает" не распространять вычисления.

Для выполнения нескольких B с одним A Вам нужен инструмент такой как split с --filter опция:

A | split [OPTIONS] --filter="B"

Это, однако, склонно испортить порядок строк в выводе, потому что задания B не будут выполнять все на той же скорости. Если это - проблема, Вы, возможно, должны были бы перенаправить B i-th вывод в промежуточный файл и сшить их вместе при использовании конца cat. Это, в свою очередь, может потребовать значительного дискового пространства.

Другие опции существуют (например, Вы могли ограничить каждый экземпляр B к выводу с буфером одной строки, ожидать, пока целый "раунд" B не закончил, выполнил эквивалент уменьшения до splitкарта, и cat временный вывод вместе), с переменными уровнями эффективности. 'Круглая' опция, просто описанная, например, будет ожидать самого медленного экземпляра B для окончания, таким образом, это будет значительно зависеть от доступной буферизации для B; [m]buffer мог бы помочь, или это не могло бы, в зависимости от того, каковы операции.

Примеры

Генерируйте первые 1 000 чисел и считайте строки параллельно:

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; т.е. если A является более тяжелым процессом, чем seq, родственник наверху split уменьшится. Но если A является очень легким процессом, и B довольно быстр (так, чтобы Вам был нужен не больше, чем B 2-3 для хранения наряду с A), затем параллелизируя с split (или каналы в целом), не могло бы хорошо стоить того.

13
27.01.2020, 19:48
  • 1
    Интересный, что разделение, найденное на Ubuntu, не имеет - опция фильтра. Какой ОС используют для этого? –  Jernej 15.06.2013, 14:15
  • 2
    Linux OpenSuSE 12.3, с coreutils (gnu.org/software/coreutils/manual/html_node / …). Я попытаюсь овладеть Ubuntu, они, возможно, изменили имя для размещения некоторого так же названного инструмента. –  LSerni 15.06.2013, 14:20
  • 3
    Вы уверенный в split --filter пропавшие без вести опции? На моей Ubuntu, 12.04-LTS ("wheezy/sid"), это там, и мои примеры действительно работают. Вы, возможно, установили другое split чем тот в GNU coreutils? –  LSerni 15.06.2013, 14:27
  • 4
    Спасибо за это. Я должен был установить более новую версию Coreutils. BTW, я заметил, что, если я запускаю программу один, она ест все ядро (100%), если я работаю | B затем, они вместе едят все ядро, обрабатывают еду 15% и обрабатывают B еда 85%.. Вы, оказывается, видите, почему это так? –  Jernej 15.06.2013, 15:36
  • 5
    Это вероятно из-за блокирования. Если B более тяжел, чем A, то A не может отправить свой вывод и замедлен. Другая возможность является уступкой B во время его операции (например, диск/сеть). В другой системе Вы могли бы видеть, что B пожрал 100% CPU1 и A, присваиваемого 18% CPU0. Вам, вероятно, нужен 85/15 ~ 5.67 = между 5 и 6 экземплярами B, чтобы заставить сингл экземпляр насыщать одноядерное. Ввод-вывод, если есть мог бы скосить эти значения, все же. –  LSerni 15.06.2013, 15:45

Теги

Похожие вопросы