Открыть список
Как стать автором
Обновить

Комментарии 58

Оригинально, а я просто процессы переназначал на разные процессоры
use xargs -P 2, luke!
Спасибо, не знал про «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 -P ... << STOP
00108
00109
00110
...
STOP


(вместо for)
Не знал об этой опции. С xargs получается так:
ls *.mts | sed 's/\(.*\).mts/\1.avi \1.mts/' | xargs -l1 -P2 echo mencoder -o
А ещё можно заменить ls на echo.
А почему бы просто не сделать стек файлов, и как только какой-нить из форкнутых процессов завершает обработку своего файла — если есть — берет из стека следующий…
Так я и собирался сделать, но пока размышлял над деталями реализации вспомнил о 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?
На разные машинах можно распараллеливать с помьщью paexec, либо перейти на transcode, где соответствующая фича уже встроена.
Давно мучал подобный вопрос, имеется папка с туевой хучей картинок, надо все их прогнать через оптимизатор. Какое правило в этом случае составлять?
all: *.png
optipng -o7 $?
скармливает все файлы одному единственному процессу

all: *.png

%.png: %.png
optipng -o7 $<
получаем циклическое правило, которое make игнорирует.
Выше же подсказали xargs -P (для меня тоже было открытием). Как-то так попробуйте:

$find -iname '*.png'|xargs -P 2 optipng -o7
cстранно, но что -P 2, что 4, что 0 всегда дают 2 процесса :/
А так?
find -iname '*.png'|xargs -P4 -l1 optipng -o7

Мне кажется, что надо опцию -l1 дать, чтобы команда optipng запускалась каждый раз с одним файлом.
То, что доктор прописал. Блин, казалось бы 3 года в линукс системах, а только вчера узнал про такую полезную функцию xargs, сегодня открыл для себя mkfifo… Сколько лет нужно, чтобы узнать более менее все? :)
Виндузятникам (мне) это всё не понять. Столько мучаться чтобы сконвертировать пару файлов. Просто интересно, сколько времени вы сэкономили? Вы написали что «загружен только один процессор из двух, а это значит, что этот процесс можно ускорить, раза в два.» Сколько это в минутах, часах, днях? ;)

Главное что бы вам нравилось, а хабрасообщество судя по всему оценило вашу первую стастью на УРА.

«Программист — это такой вид идиота, который потратит час, чтобы пятиминутную ручную работу за него за 3 секунды сделал компьютер» не помню от куда.
Дада
точить топор? ты что, некогда! руби быстрее и баста!
тоже не помню, откуда.
пля, это про меня))))
Один помучался — решил, другие мучаться не будут и воспользуются готовым решением. Автор потенциально сэкономил кому-то некоторое количество времени.

Ну и сам себе тоже, если в будущем опять понадобится.
А главное — получил удовольсвие от создания [полезной] штуки.
Да и свечку вы тоже, небось, не держали. Может, у него 20 файлов, а может 20k.
И самое главное — ну не осчастливили Linux софтом типа «Super Duper Advanced Video Converter Pro» (всего за $24.99!!). Вот нам, несчастным, и приходится извращаться.
Да я что против чтоли? Я просто говорю что со стороны, тем кто не в курсе… это выглядит забавно.
виндузятник (вы), упустили самое главное: это не топик о конвертировании видео, это топик о распараллеливании задач, а приведенный автором пример подойдет для множества случаев, где на выходе у параллелных процессов будут некие файлы.
Так то!
(с) К.О.
> Вы написали что «загружен только один процессор из двух, а это значит, что
> этот процесс можно ускорить, раза в два.»
> Сколько это в минутах, часах, днях? ;)


Всё зависит от кодируемых файлов — если они кодировались в один поток три часа, то в два потока с большой вероятностью перекодируются за полтора. Автор же написал «можно ускорить раза в два» ;)
Спасибо Капитан. Мне было интересно, сколько ИМЕННО в этом случае автор экономит.

На мой вопрос ответил Frosty — habrahabr.ru/blogs/linux/66903/#comment_1885424
Да, не совсем понял суть вопроса. Просто после цитирования и просьбы уточнить «это в минутах, часах, днях» как-то «затерялся» предшествующий вопрос к автору…
Но судя по расширению файлов довольно большая вероятность, что там видео в HD, а так как конвертировать надо было не пару файлов, а побольше, то и экономия, думаю, довольно существенная. Даже если экономия была бы всего полчаса, это уже хорошо, так как на чтение манов этого достаточно, т.е. здесь во времени не теряем вовсе, а в будущем получаем существенную экономию.
В данном примере кодилось всё в 22 мегабитный поток, значит и видео не маленькое, и качество хотелось сохранить приемлемое. Попробуйте у себя на компе пару десятиминутных видеороликов сконвертировать с хорошим качеством, думаю, что экономия данного способа для бОльшего количества файлов сразу будет на лицо ;)
из 6 минутный mkv,H264 AVC 1280x720 25fps AC3 5.1ch 48kHz в avi,XviD 702x396 30fps (забыл поменять), 3mbps, MP3 160kbps

Конвертилось 12 минут, обя ядра на 92% заюзаны, температура до 74 поднялась.

Это если выстовить в проге приоритет 100%.

Ну и как сэкономить? :)
Ну если кодить для мобильника в 320x240 (т.е. получается в 320x180), то оно вообще закодируется за пару минут, а то и быстрее. В приведённом примере автора я не заметил ресайза видео и поток 22 мегабита вряд ли нужен для 720p, так что при тестировании Вы сильно упростили задачу взяв менее «тяжёлое» видео и закодировав в ещё более «лёгкое», чем источник. Кстати, Вы не указали параметры Motion precision, а они играют очень большую роль в скорости кодирования и качестве результата ;)
У меня на компе, для примера, в подобное разрешение (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.
ffmpeg кстати нет, а жаль.
по умолчанию — нет, а если собрать руками и указать ключик --enable-pthreads то будет.
Ffmpeg нужно ставить отдельно, или подойдет тот, что в комплекте исходников mplayer?
не, я про отдельный, а тот что в мплеере — нужно флаги смотреть.
Такой способ, к сожалению, подходит лишь тем, кто крепко держит в руках консоль и svn. :)
В Gentoo ебилд ffmpeg'а имеет USE-флаг threads который добавляет этот самый --enable-pthreads, также есть ебилд с который сам достает самое свежее из svn.
Еще помнится, что с помощью make iso-образы можно весело создавать
Интересно бы узнать ;)
Автор, а не напишите ли хабратопик на эту тему???)
make -j — отличная вещь :)
Статья хорошая, просто хотелось отметить, что перекодирование видео должно скорее в скорость записи на винчестер упереться, чем в процессор. В смысле загрузить два процессора на полную скорее всего уже не выйдет.
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Смотря во что кодировать.
Если в h.264 с тонной ресурсоемких опций, то скорость обработки более 10 fps/ядро получить трудно.
Если задачи работают примерно одинаковое время, можно вручную раскидать их по ядрам при помощи утилиты taskset.
Во-первых, спасибо за пост, полезно, интересно и юзабельно.

Правда, то ли у меня другая сборка mencoder, то ли по-другому настроена система, но оба ядра Turion 64 загружены на 100% еще с первого способа:)
Так что полезным оказалось скорее скармливание списка файлов.
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.