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