Назад | Перейти на главную страницу

Bash Распараллеливание процессов, интенсивно использующих ЦП

tee перенаправляет свой стандартный ввод в каждый указанный файл, а pee делает то же самое, но для труб. Эти программы отправляют каждую строку своего стандартного ввода в каждый указанный файл / канал.

Однако я искал способ «сбалансировать загрузку» стандартного ввода для разных каналов, чтобы одна строка отправлялась на первый канал, другая строка - на второй и т. Д. Также было бы неплохо, если бы stdout каналов собирался в один поток.

Вариант использования - простое распараллеливание процессов, интенсивно использующих ЦП, которые работают построчно. Я делал sed в файле размером 14 ГБ, и он мог бы работать намного быстрее, если бы я мог использовать несколько sed процессы. Команда была такой:

pv infile | sed 's/something//' > outfile

Для распараллеливания лучше всего, если GNU parallel будет поддерживать эту функцию таким образом (составлял --demux-stdin вариант):

pv infile | parallel -u -j4 --demux-stdin "sed 's/something//'" > outfile

Однако такого варианта нет и parallel всегда использует свой стандартный ввод в качестве аргументов для команды, которую он вызывает, например xargs. Я попробовал это, но это безнадежно медленно, и понятно почему:

pv infile | parallel -u -j4 "echo {} | sed 's/something//'" > outfile

Я просто хотел знать, есть ли другой способ сделать это (кроме самого написания кода). Если бы была «балансировка нагрузки» tee (назовем это lee), Я мог сделать это:

pv infile | lee >(sed 's/something//' >> outfile) >(sed 's/something//' >> outfile) >(sed 's/something//' >> outfile) >(sed 's/something//' >> outfile)

Не очень, поэтому я определенно предпочитаю что-то вроде накрашенного parallel версия, но это тоже сработает.

Мы обсуждаем, как реализовать именно эту функцию в списке рассылки GNU Parallel прямо сейчас. http://lists.gnu.org/archive/html/parallel/2011-01/msg00001.html

Не стесняйтесь присоединяться: http://lists.gnu.org/mailman/listinfo/parallel

Теперь прототип готов к тестированию: http://lists.gnu.org/archive/html/parallel/2011-01/msg00015.html

Я бы посмотрел на реализацию этого в Perl с Параллель :: ForkManager. Вы можете выполнить разделение строк в скрипте, а затем передать полученные строки в процессы Parallel :: ForkManager. Использование run_on_finish обратный вызов для сбора вывода. Очевидно, что для вашего примера sed вы могли бы просто выполнить текстовую операцию в perl и, возможно, использовать что-то вроде AnyEvent для обработки параллелизма.