Я пишу крошечный сценарий, который называет "PNGOUT" util на нескольких сотнях файлов PNG. Я просто сделал это:
find $BASEDIR -iname "*png" -exec pngout {} \;
И затем я посмотрел на свой монитор ЦП и заметил, что только одно из ядра использовалось, который довольно печален.
В этот день и возраст двойных, квадратических, octo и hexa (?) рабочего стола ядер, как я просто параллелизирую эту задачу с Bash? (это не первый раз, когда у меня была такая потребность, поскольку довольно много этих utils является монопоточным... У меня уже был случай с mp3 кодерами).
Был бы, просто выполняя весь pngout, в фоновом режиме делают? Как был бы моя команда находки быть похожей затем? (Я не слишком уверен, как смешаться, находят и '&' символ),
Я, если бы имеют три сотни изображений, это означало бы подкачивать между тремя сотнями процессов, который не кажется большим так или иначе!?
Или я должен скопировать свои три сотни файлов или так в "nb директора", где "nb директора" был бы количество ядер, затем работало бы одновременно "nb, находит"? (который был бы достаточно близок),
Но как я сделал бы это?
Отвечая на свой собственный вопрос... Оказывается, есть относительно неизвестная функция команды xargs, которую можно использовать для достижения этой цели:
find . -iname "*png" -print0 | xargs -0 --max-procs=4 -n 1 pngout
Бинго, мгновенное ускорение в 4 раза на четырехъядерной машине :)
порождать все задачи в фоновом режиме:
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
это не оптимально, поскольку он ждет, пока все одновременные задачи закончатся, чтобы начать другую группу; но это лучше, чем ничего.
Параллелизация редко бывает тривиальной. В вашем случае, если вы можете уникально выбирать файлы в одинаковые по размеру наборы, то вы можете запустить несколько копий вашего сценария 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