Bash: как просто параллелизировать задачи?

Я пишу крошечный сценарий, который называет "PNGOUT" util на нескольких сотнях файлов PNG. Я просто сделал это:

find $BASEDIR -iname "*png" -exec pngout {} \;

И затем я посмотрел на свой монитор ЦП и заметил, что только одно из ядра использовалось, который довольно печален.

В этот день и возраст двойных, квадратических, octo и hexa (?) рабочего стола ядер, как я просто параллелизирую эту задачу с Bash? (это не первый раз, когда у меня была такая потребность, поскольку довольно много этих utils является монопоточным... У меня уже был случай с mp3 кодерами).

Был бы, просто выполняя весь pngout, в фоновом режиме делают? Как был бы моя команда находки быть похожей затем? (Я не слишком уверен, как смешаться, находят и '&' символ),

Я, если бы имеют три сотни изображений, это означало бы подкачивать между тремя сотнями процессов, который не кажется большим так или иначе!?

Или я должен скопировать свои три сотни файлов или так в "nb директора", где "nb директора" был бы количество ядер, затем работало бы одновременно "nb, находит"? (который был бы достаточно близок),

Но как я сделал бы это?

12
задан NoozNooz42 9 June 2010 в 01:12
поделиться

3 ответа

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

find . -iname "*png" -print0 | xargs -0 --max-procs=4 -n 1 pngout

Бинго, мгновенное ускорение в 4 раза на четырехъядерной машине :)

22
ответ дан 2 December 2019 в 05:27
поделиться

порождать все задачи в фоновом режиме:

find $BASEDIR -iname "*png" | while read f; do
  pngout "$f" &
done

но, конечно, это не лучший вариант. выполнять 'n' задач за раз:

i=0
find $BASEDIR -iname "*png" | while read f; do
  pngout "$f" &
  i=$((i+1))
  if [[ $i -gt $NTASKS ]]; then
    wait
    i=0
  fi
done

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

4
ответ дан 2 December 2019 в 05:27
поделиться

Параллелизация редко бывает тривиальной. В вашем случае, если вы можете уникально выбирать файлы в одинаковые по размеру наборы, то вы можете запустить несколько копий вашего сценария find. Вы же не хотите запускать 300 картинок в фоновом режиме. Для подобных заданий обычно быстрее запускать их последовательно. Фоновый режим команды или использование пакетной обработки - оба возможных варианта.

Предполагая, что файлы последовательно пронумерованы, можно использовать шаблон поиска типа "[0-4].png" для одного поиска и "[5-9].png" для другого. Таким образом, два ядра будут работать примерно одинаковое количество времени.

Выполнение задачи на ферме потребует установки диспетчера-бегуна. Создание, тестирование и запуск этой системы займет довольно много времени.

Запустите BOINC, чтобы использовать свободные процессоры. Вы, вероятно, захотите игнорировать niced-процессы при мониторинге частоты процессора. Добавьте такой код в rc.local.

for CPU in /sys/devices/system/cpu/cpu[0-9]*; do
    echo 1 > ${CPU}/cpufreq/ondemand/ignore_nice_load
done
2
ответ дан 2 December 2019 в 05:27
поделиться
Другие вопросы по тегам:

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