Комментарии 58
Оригинально, а я просто процессы переназначал на разные процессоры
Спасибо, не знал про «xargs -P».
наверно, вот так должно работать:
наверно, вот так должно работать:
#!/bin/sh -e opts='-ovc x264 -x264encopts bitrate=22000:keyint=50 -oac mp3lame -lameopts vbr=3:br=320 -fps 50' ( for n in 00108 00109 00110 00111 00118 00119 00120 00123; do echo $n done ) | xargs -P 2 -J % mencoder -o input/%.mts %.avi $opts
Не знал об этой опции. С xargs получается так:
ls *.mts | sed 's/\(.*\).mts/\1.avi \1.mts/' | xargs -l1 -P2 echo mencoder -o
ls *.mts | sed 's/\(.*\).mts/\1.avi \1.mts/' | xargs -l1 -P2 echo mencoder -o
А почему бы просто не сделать стек файлов, и как только какой-нить из форкнутых процессов завершает обработку своего файла — если есть — берет из стека следующий…
Так я и собирался сделать, но пока размышлял над деталями реализации вспомнил о make.
А разве не в этом состоит решение, предложенное автором? Задаётся набор («стек») файлов, указывается, каким образом их обрабатывать и затем указывается, какое количество рабочих процессов использовать. Ровно то, что Вы сказали — но в 3 строки (+аргумент при запуске make).
У Вас есть вариант короче и изящнее? Поделитесь :)
У Вас есть вариант короче и изящнее? Поделитесь :)
ну, не изящнее, но… ;)
#!/bin/bash # список чего-нить list="mail.ru ya.ru google.ru" i=1 # функция обработки test() { echo start $1 ping -c 3 $1 > /dev/null echo end $1 } # параметр - количество одновременных процессов limit=$1 a=1 while true do param=$(echo $list | awk "{print \$$a}") if [ $param ] then # для того, чтобы убедиться # jobs jobs=$(jobs | wc -l) if (( jobs < limit)) then test $param & (( a++ )) # чтобы не было расхода процессора - раскомментируйте: (просто иначе на пингах не видно ;)) # sleep 1 fi else break fi done wait
зы: i тан не нужен ;)
проверил на архивировании файлов — если тупо все в цикле запараллелить, без контроля количества процессов — чуть-чуть медленнее (5% примерно), чем 4 процесса с контролем количества.
all: mail.ru ya.ru google.ru
%.ru:
echo "start $@"; ping -c 3 $@ 1>/dev/null; echo "finish $@"
$ make -j 2
;)
«мы тут с мужиками подумали, и...»
в общем, изящный вариант, который на раз-два переделывается под командную строку:
в общем, изящный вариант, который на раз-два переделывается под командную строку:
#!/bin/bash list="mail.ru fignya.ya ya.ru google.ru mista.ru" test() { echo start $1 ping -c 3 $1 > /dev/null echo end $1 } limit=$1 func() { while [ $1 ]; do if (( `jobs | wc -l` < limit )); then test $1 & shift fi done } # а если передавать все командной строкой - то shift; func $@ func $list wait
Шедевр. Честно.
Мои Вам хабрареспекты.
Мои Вам хабрареспекты.
Автор молодец! Использование стандартных средств (make) в нестандартных задачах (mencoder)! Умение мыслить широко и нестандартно — большой плюс для специалиста!
Замечательная тема, особенно приятно смотреть как ускоряет компиляцию чего-нибудь тяжелого make -j4 )
Очаровательно.
А что там с xargs? Что дает по сравнению с make?
А что там с xargs? Что дает по сравнению с make?
Давно мучал подобный вопрос, имеется папка с туевой хучей картинок, надо все их прогнать через оптимизатор. Какое правило в этом случае составлять?
all: *.png
optipng -o7 $?
скармливает все файлы одному единственному процессу
all: *.png
%.png: %.png
optipng -o7 $<
получаем циклическое правило, которое make игнорирует.
all: *.png
optipng -o7 $?
скармливает все файлы одному единственному процессу
all: *.png
%.png: %.png
optipng -o7 $<
получаем циклическое правило, которое make игнорирует.
Выше же подсказали xargs -P (для меня тоже было открытием). Как-то так попробуйте:
$find -iname '*.png'|xargs -P 2 optipng -o7
$find -iname '*.png'|xargs -P 2 optipng -o7
cстранно, но что -P 2, что 4, что 0 всегда дают 2 процесса :/
А так?
find -iname '*.png'|xargs -P4 -l1 optipng -o7
Мне кажется, что надо опцию -l1 дать, чтобы команда optipng запускалась каждый раз с одним файлом.
find -iname '*.png'|xargs -P4 -l1 optipng -o7
Мне кажется, что надо опцию -l1 дать, чтобы команда optipng запускалась каждый раз с одним файлом.
Виндузятникам (мне) это всё не понять. Столько мучаться чтобы сконвертировать пару файлов. Просто интересно, сколько времени вы сэкономили? Вы написали что «загружен только один процессор из двух, а это значит, что этот процесс можно ускорить, раза в два.» Сколько это в минутах, часах, днях? ;)
Главное что бы вам нравилось, а хабрасообщество судя по всему оценило вашу первую стастью на УРА.
Главное что бы вам нравилось, а хабрасообщество судя по всему оценило вашу первую стастью на УРА.
«Программист — это такой вид идиота, который потратит час, чтобы пятиминутную ручную работу за него за 3 секунды сделал компьютер» не помню от куда.
Один помучался — решил, другие мучаться не будут и воспользуются готовым решением. Автор потенциально сэкономил кому-то некоторое количество времени.
Ну и сам себе тоже, если в будущем опять понадобится.
Ну и сам себе тоже, если в будущем опять понадобится.
виндузятник (вы), упустили самое главное: это не топик о конвертировании видео, это топик о распараллеливании задач, а приведенный автором пример подойдет для множества случаев, где на выходе у параллелных процессов будут некие файлы.
Так то!
(с) К.О.
Так то!
(с) К.О.
> Вы написали что «загружен только один процессор из двух, а это значит, что
> этот процесс можно ускорить, раза в два.»
> Сколько это в минутах, часах, днях? ;)
Всё зависит от кодируемых файлов — если они кодировались в один поток три часа, то в два потока с большой вероятностью перекодируются за полтора. Автор же написал «можно ускорить раза в два» ;)
> этот процесс можно ускорить, раза в два.»
> Сколько это в минутах, часах, днях? ;)
Всё зависит от кодируемых файлов — если они кодировались в один поток три часа, то в два потока с большой вероятностью перекодируются за полтора. Автор же написал «можно ускорить раза в два» ;)
Спасибо Капитан. Мне было интересно, сколько ИМЕННО в этом случае автор экономит.
На мой вопрос ответил Frosty — habrahabr.ru/blogs/linux/66903/#comment_1885424
На мой вопрос ответил Frosty — habrahabr.ru/blogs/linux/66903/#comment_1885424
Да, не совсем понял суть вопроса. Просто после цитирования и просьбы уточнить «это в минутах, часах, днях» как-то «затерялся» предшествующий вопрос к автору…
Но судя по расширению файлов довольно большая вероятность, что там видео в HD, а так как конвертировать надо было не пару файлов, а побольше, то и экономия, думаю, довольно существенная. Даже если экономия была бы всего полчаса, это уже хорошо, так как на чтение манов этого достаточно, т.е. здесь во времени не теряем вовсе, а в будущем получаем существенную экономию.
В данном примере кодилось всё в 22 мегабитный поток, значит и видео не маленькое, и качество хотелось сохранить приемлемое. Попробуйте у себя на компе пару десятиминутных видеороликов сконвертировать с хорошим качеством, думаю, что экономия данного способа для бОльшего количества файлов сразу будет на лицо ;)
Но судя по расширению файлов довольно большая вероятность, что там видео в HD, а так как конвертировать надо было не пару файлов, а побольше, то и экономия, думаю, довольно существенная. Даже если экономия была бы всего полчаса, это уже хорошо, так как на чтение манов этого достаточно, т.е. здесь во времени не теряем вовсе, а в будущем получаем существенную экономию.
В данном примере кодилось всё в 22 мегабитный поток, значит и видео не маленькое, и качество хотелось сохранить приемлемое. Попробуйте у себя на компе пару десятиминутных видеороликов сконвертировать с хорошим качеством, думаю, что экономия данного способа для бОльшего количества файлов сразу будет на лицо ;)
из 6 минутный mkv,H264 AVC 1280x720 25fps AC3 5.1ch 48kHz в avi,XviD 702x396 30fps (забыл поменять), 3mbps, MP3 160kbps
Конвертилось 12 минут, обя ядра на 92% заюзаны, температура до 74 поднялась.
Это если выстовить в проге приоритет 100%.
Ну и как сэкономить? :)
Конвертилось 12 минут, обя ядра на 92% заюзаны, температура до 74 поднялась.
Это если выстовить в проге приоритет 100%.
Ну и как сэкономить? :)
Ну если кодить для мобильника в 320x240 (т.е. получается в 320x180), то оно вообще закодируется за пару минут, а то и быстрее. В приведённом примере автора я не заметил ресайза видео и поток 22 мегабита вряд ли нужен для 720p, так что при тестировании Вы сильно упростили задачу взяв менее «тяжёлое» видео и закодировав в ещё более «лёгкое», чем источник. Кстати, Вы не указали параметры Motion precision, а они играют очень большую роль в скорости кодирования и качестве результата ;)
У меня на компе, для примера, в подобное разрешение (720x???) видео кодируется в худшем случае со скоростью один к одному (при сохранении хорошего качества), так что подобная перекодировка заняла бы максимум 6 минут, а скорее всего даже меньше.
Но ведь и при своём тесте Вы должны были увидеть экономию при многопоточности. У Вас один видеоролик кодировался 12 минут, т.е. при перекодировании на одном ядре этот процесс занял бы около 24 минут, значит Вы сэкономили 12 минут. У автора топика в примере восемь видеофайлов, значит если бы это были коротенькие видео 720p и кодировались бы для просмотра на обычном телевизоре, то на Вашем компьютере такое распараллеливание сэкономило бы полтора часа как минимум. Считайте, что Вы сами ответили на свой вопрос.
У меня на компе, для примера, в подобное разрешение (720x???) видео кодируется в худшем случае со скоростью один к одному (при сохранении хорошего качества), так что подобная перекодировка заняла бы максимум 6 минут, а скорее всего даже меньше.
Но ведь и при своём тесте Вы должны были увидеть экономию при многопоточности. У Вас один видеоролик кодировался 12 минут, т.е. при перекодировании на одном ядре этот процесс занял бы около 24 минут, значит Вы сэкономили 12 минут. У автора топика в примере восемь видеофайлов, значит если бы это были коротенькие видео 720p и кодировались бы для просмотра на обычном телевизоре, то на Вашем компьютере такое распараллеливание сэкономило бы полтора часа как минимум. Считайте, что Вы сами ответили на свой вопрос.
Экономия на времени кодирования получилась где-то в 2 часа, скрипты писал минут 10 вспоминая суфиксные правила GNU make + часа два на написании статьи и общее время проведеное на хабр.
В mencoder XviD и x264 уже поддерживают многопоточность искаропки.
man mencoder:
xvidencopts
The following option is only available in the 1.2.x version of Xvid.
threads=
Create n threads to run the motion estimation (default: 0). The maximum number
of threads that can be used is the picture height divided by 16.
x264encopts
threads=
Spawn threads to encode in parallel on multiple CPUs (default: 1). This has a
slight penalty to compression quality. 0 or 'auto' tells x264 to detect how
many CPUs you have and pick an appropriate number of threads.
man mencoder:
xvidencopts
The following option is only available in the 1.2.x version of Xvid.
threads=
Create n threads to run the motion estimation (default: 0). The maximum number
of threads that can be used is the picture height divided by 16.
x264encopts
threads=
Spawn threads to encode in parallel on multiple CPUs (default: 1). This has a
slight penalty to compression quality. 0 or 'auto' tells x264 to detect how
many CPUs you have and pick an appropriate number of threads.
ffmpeg кстати нет, а жаль.
по умолчанию — нет, а если собрать руками и указать ключик --enable-pthreads то будет.
Ffmpeg нужно ставить отдельно, или подойдет тот, что в комплекте исходников mplayer?
не, я про отдельный, а тот что в мплеере — нужно флаги смотреть.
Еще помнится, что с помощью make iso-образы можно весело создавать
Статья хорошая, просто хотелось отметить, что перекодирование видео должно скорее в скорость записи на винчестер упереться, чем в процессор. В смысле загрузить два процессора на полную скорее всего уже не выйдет.
Если задачи работают примерно одинаковое время, можно вручную раскидать их по ядрам при помощи утилиты taskset.
Во-первых, спасибо за пост, полезно, интересно и юзабельно.
Правда, то ли у меня другая сборка mencoder, то ли по-другому настроена система, но оба ядра Turion 64 загружены на 100% еще с первого способа:)
Так что полезным оказалось скорее скармливание списка файлов.
Правда, то ли у меня другая сборка mencoder, то ли по-другому настроена система, но оба ядра Turion 64 загружены на 100% еще с первого способа:)
Так что полезным оказалось скорее скармливание списка файлов.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Распараллеливание задач в Linux