Přemýšlel jsem nad tím, jak vyřešit vícevláknovou kompresi souborů mp3. Nedávno byla v diskusi debata na toto téma. Bylo to spíš takové hraní, ale pokud vás zajímá jednoduché řešení, nabízím jeho popis.
Když se v diskusích objevilo téma Využití více jader, také jsem přemýšlel, jak elegantně problém vyřešit. Svou ideu jsem v diskusi naznačil. Je jasné, že se nejedná o ideální řešení.
Hodí se ve chvíli, kdy potřebujeme zpracovat hromadu úloh, které nám zaberou přibližně stejnou dobu – tedy ideální například na kompresi mp3. Většina skladeb má totiž podobnou délku a doba jejich zpracování bude velmi podobná.
Před pár dny jsem chtěl zkomprimovat jedno album a tak jsem se rozhodl, že se pustím do psaní skriptu, který mi vše urychlí. Nejde ani tak o ten samotný výkon, ale o to dokázat si, že to jde. Jeden kolega to shrnul slovy: „Aha, takže teď se Ti to album nekomprimuje čtyři minuty, ale dvě a půl“ Je jasné, že výkon počítače není problém. Ale když už tam ta jádra jsou…
Výsledný skript vypadá takto:
#!/bin/bash ls *.wav|while read "soubor" do echo "Delam mp3 z $soubor" nice -19 lame -m j --quiet --vbr-new -b 64 -B 192 "$soubor" "$soubor.mp3" & read "soubor" if [ -z "$soubor" ] then wait continue fi echo "Delam mp3 z $soubor" nice -19 lame -m j --quiet --vbr-new -b 64 -B 192 "$soubor" "$soubor.mp3" & wait done
Netvrdím, že je to nejlepší řešení. Spíš bych to nazval „proof of concept“ tedy důkaz, že to i takto jde.
Jak to funguje? Nejprve získám z aktuálního adresáře seznam wav souborů, pak na první z nich pustím lame na pozadí. Pak načtu další název a ověřím, jestli jsem něco dostal (pokud by už byl konec seznamu wavů, skript končí). Pokud ano, pak se pustí druhý lame opět na pozadí. Pak přichází klíčový příkaz wait
, který čeká, až úlohy na pozadí skončí. Poté, pokud ještě nějaké soubory v seznamu zbývají, se skript opakuje.
Skutečně to funguje, skript po většinu doby vytěžuje obě jádra. Je jasné, že pokud by byla některá skladba podstatně kratší než druhá, došlo by u jednoho jádra k prostoji (čekalo by, až doběhne delší práce), ale na tom mi příliš nesejde.
Jedná se o velmi jednoduché řešení, které prostě funguje. Ve zmiňované diskusi bylo načtrnuto více možností, mě osobně se nejvíce líbil nápad s Make, který je zcela univerzální, netrpí „prostoji“, ale zase na druhou stranu to není o několika řádcích skriptu. Časem ho ale možná taky zkusím realizovat.
Dovolil bych si navrhnout ještě jedno řešení, pro libovolný počet procesorů:
priorita=1
for soubor in $(ls -S1 *.wav); do
nice -$priorita lame -m j --quiet --vbr-new -b 64 -B 192 "$soubor" "$soubor.mp3" &
if [ $priorita -lt 19 ]; then
priorita=$(($priorita+1))
fi
done
To udělá to, že se pokusí všechny soubory převést najednou a ať si to procesory mezi sebou už nějak rozdělí. Kromě toho se začne těmi největšími soubory (a mají také nejvyšší prioritu), takže je menší pravděpodobnost, že se bude na nějakou dlouhou písničku čekat. Nevýhoda: load se zvedne na číslo počtu písniček :-) Ale nezkoušel jsem, nevím jak moc to vadí, když všechny procesy mají i tak nízkou prioritu.
Mno, je vidět, že shell je spíš tak hraní. Když se použije jazyk s rozumným interface na systém, tak se z toho dá vytáhnout víc ;)
Mám doma něco podobného v perlu, který si zajistí vše od stáhnutí z CD, ke kompresi, nastavení tags, o možnosti výběru mezi ogg/mp3 samozřejmě ani nemluvě. Počet paralelně běžících kompresí je samozřejmě nastavitelný, další se pouští okamžitě, nikoli poté, co doběhnou všechny běžící.
Nedostatkem je, ze se napred to CD musi vyripovat a to nikoliv paralelne na dvou procesech. Nevim, co timhle postupem usetrim napr. proti Kaudiokreatoru, ktery na jedne strane ripuje, na druhe pak vyripovane tracky rve do fronty, odkud si je bere lame, jak stiha. Navic jeste ty tracky otaguje podle freedb, coz tenhle skript asi neudela, protoze nevim, odkud by ty tagy vydoloval, z wavu asi tezko.
Cili postup je takovyto: Vyripovat a pekne pockat, az to dojede do konce, namisto aby se zacalo kodovat, jakmile je prvni track ripnuty. Pak si to zrychlene zakodovat ve dvou procesech. Nasledne uz jen rucne otagovat, coz bude trvat rekneme pul hodiny.
Cili se jedna opravdu o proof of concept, kterym si clovek akorat pridela praci a vse pekne prodlouzi, i kdyz, dluzno poznamenat, faze kodovani bude kratsi. :-)
[9] To mi prijde jako skoda mista - skladovat wav. Zkusil bych ukladat primo g711 a pak konvertovat rovnou. Lame se teda musi prelozit s podporou libsndfile (http://www.mega-nerd.com/libsndfile/).
Petr Krčmář pracuje jako šéfredaktor serveru Root.cz. GNU/Linuxem a Unixem obecně se zabývá již více než deset let a věnuje se především jeho nasazení v počítačových sítích a bezpečnostní politice. Zde bloguje o Root.cz, Linuxu, internetu a světě kolem sebe.
Přečteno 110 689×
Přečteno 89 225×
Přečteno 72 546×
Přečteno 57 874×
Přečteno 54 224×