Рассмотрим следующий сценарий. У меня есть две программы A и B. Программа A выводит в stdout строки строк, в то время как программа B обрабатывает строки из stdin. Способ использовать эти две программы, конечно:
foo @ bar: ~ $ A | В
Теперь я заметил, что это съедает только одно ядро; отсюда мне интересно:
Программы А и В совместно используют одни и те же вычислительные ресурсы? Если так, есть ли способ запустить A и B одновременно?
Еще одна вещь, которую я заметил, заключается в том, что A работает намного быстрее, чем B, поэтому мне интересно, может ли каким-то образом запускать больше программ на B и позволить им обрабатывать строки, которые A выводит параллельно.
То есть, A выводил бы свои строки, и было бы N экземпляров программ B, которые читали бы эти строки (кто бы ни читал их в первую очередь), обрабатывали их и выводили их на стандартный вывод.
Итак, мой последний вопрос:
Есть ли способ передать вывод в A среди нескольких процессов B, не заботясь о состоянии гонки и других несоответствиях, которые могут потенциально возникнуть?
источник
A | B | C
параллельно , как в отдельных процессах, в связи с характером труб (В должен ждать выхода A, C должен ждать выхода B) он все еще может быть линейным , в некоторых случаях. Это полностью зависит от того, какую продукцию они производят. Существует не так много случаев, когда многократный запускB
мог бы сильно помочь, вполне возможно, что пример параллельного wc медленнее обычного,wc
поскольку для расщепления может потребоваться больше ресурсов, чем для обычного подсчета строк. Используйте с осторожностью.Ответы:
Проблема
split --filter
в том, что выходные данные могут быть перепутаны, поэтому вы получите половину строки от процесса 1, а затем половину строки от процесса 2.GNU Parallel гарантирует, что не будет путаницы.
Итак, предположим, что вы хотите сделать:
Но этот B ужасно медленный, и поэтому вы хотите распараллелить это. Тогда вы можете сделать:
GNU Parallel по умолчанию разделяется на \ n и имеет размер блока 1 МБ. Это можно настроить с помощью --recend и --block.
Вы можете найти больше информации о GNU Parallel по адресу: http://www.gnu.org/s/parallel/
Вы можете установить GNU Parallel всего за 10 секунд с помощью:
Посмотрите вступительное видео на http://www.youtube.com/playlist?list=PL284C9FF2488BC6D1
источник
--block-size
будет зависеть от объема оперативной памяти и от того, насколько быстро вы сможете начать новуюB
. В вашей ситуации я бы использовал--block 100M
и посмотрел, как это выполняется.sh
- отлично. Проблема заключается в передаче его sh: загрузка и запуск исполняемого кода с сайта . Имейте в виду, может быть, я просто слишком параноик, поскольку можно возразить, что пользовательский RPM или DEB - это одно и то же, и даже размещение кода на странице для копирования и вставки приведет к тому, что люди будут делать это вслепую. тем не мение.Когда вы пишете
A | B
, оба процесса уже работают параллельно. Если вы видите, что они используют только одно ядро, это может быть связано либо с настройками привязки к процессору (возможно, есть какой-то инструмент для запуска процесса с другой привязкой), либо потому, что одного процесса недостаточно для хранения всего ядра и системы ». Предпочитает «не распространять вычисления».Чтобы запустить несколько B с одним A, вам нужен инструмент, например,
split
с--filter
опцией:Это, однако, может испортить порядок строк в выходных данных, поскольку задания B не будут выполняться с одинаковой скоростью. Если это проблема, вам может понадобиться перенаправить вывод i-го файла в промежуточный файл и сшить их вместе в конце, используя
cat
. Это, в свою очередь, может потребовать значительного дискового пространства.Существуют и другие параметры (например , вы могли бы ограничить каждый экземпляр B к одной линии буферизации вывода, ждать , пока весь «круглый» из Б закончила, не запустить эквивалент уменьшить до
split
S» карт , а такжеcat
временный выход вместе), с различными уровнями эффективности. Опция 'round', например, только что описанная, будет ожидать завершения самого медленного экземпляра B , поэтому она будет сильно зависеть от доступной буферизации для B;[m]buffer
может помочь, а может и нет, в зависимости от операций.Примеры
Сгенерируйте первые 1000 чисел и сосчитайте линии параллельно:
Если бы мы «пометили» строки, мы бы увидели, что каждая первая строка отправляется в процесс № 1, каждая пятая строка - в процесс № 5 и так далее. Более того, за то время, которое требуется
split
для запуска второго процесса, первый уже является хорошим способом в его квоте:При выполнении на 2-жильную машине,
seq
,split
иwc
процессы совместно сердечник; но при ближайшем рассмотрении система оставляет первые два процесса на CPU0 и делит CPU1 между рабочими процессами:Особенно обратите внимание, что
split
кушает значительное количество процессоров. Это будет уменьшаться пропорционально потребностям А; то есть, если A более тяжелый процесс, чемseq
, относительные накладные расходыsplit
уменьшатся. Но если A - очень легкий процесс, а B - довольно быстрый (так что вам нужно не больше, чем 2-3 B, чтобы держаться вместе с A), то распараллеливание сsplit
(или трубами в целом) может не стоить этого.источник
split
--filter
опция отсутствует? На моем Ubuntu 12.04-LTS ("wheezy / sid") он есть, и мои примеры работают. Не могли бы вы установить другой,split
чем в GNU coreutils?