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

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

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

И затем я посмотрел на свой монитор процессора и заметил, что используется только одно из ядро, что довольно грустно.

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

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

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

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

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

Ответ 1

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

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

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

Ответ 2

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

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

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

Ответ 3

Параллеллизация редко тривиальна. В вашем случае, если вы можете выбирать файлы уникально в наборах с равным размером, вы можете запускать несколько копий своего поиска script. Вы не хотите запускать 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