Paralelní zpracování souboru

beer

  • *****
  • 729
    • Zobrazit profil
Paralelní zpracování souboru
« kdy: 21. 02. 2018, 12:32:59 »
Ahoj, vytvořil jsem si soubor pro optimalizaci obrázků na web serveru. Konfigurační příklady, které jsem na webu našel, byly velmi neefektivní, protože jedou jen v jednom vlákně a zkouší i soubory, které již byly optimalizovány.

Napadlo mne, že by bylo efektivnější obrázky nejprve seřadit dle velikosti a zařadit do fronty. To mi jakžtakž funguje, ale jen na jednom stroji s debianem 9, na ubuntu 17.10 mám chybové hlášky o tom, že to někde nemá ve složce přístup (zkoušel jsem do /tmp přesunout pár obrázků a zkoušel to tam), obrázky se ale v /tmp neoptimalizovali, přitom jsem použil stejný postup jako na web serveru mujscript.sh /tmp/.

Koukal jsem na nějaké příklady paralelního zpracování, ale moc se v tom neorientuji. Koukal jsem i na program Parallel, ale ne že bych z toho byl zrovna moudrý.

Zde je můj současný skript:

Kód: [Vybrat]
#!/bin/bash
target="$1"

jpgfronta="$(mktemp)"
pngfronta="$(mktemp)"

find "${target}/" -type f -iname *.jp*g -exec du -a {} + | sort -n -r | cut -f 2 >"$jpgfronta"
find "${target}/" -type f -iname *.png -exec du -a {} + | sort -n -r | cut -f 2 >"$pngfronta"

while read line
do
printf "%s\n" "$line"
jpeg-recompress -q medium -l 128 -a -c -m smallfry "$(printf "%s\n" "$line")" "$(printf "%s\n" "$line")"
done < "$jpgfronta" &

while read line
do
printf "%s\n" "$line"
optipng -quiet -o7 "$(printf "%s\n" "$line")"
done < "$pngfronta" &

rm "$jpgfronta"
rm "$pngfronta"

exit

Myslím, že by bylo efektivnější, kdyby se zpracovávali najednou soubory dle počtu jader, jedno jádro by se nechalo nevyužité. Ve frontě jsou názvy souborů pro zpracování, v jednom sloupci. Možná by bylo jednodušší soubor rozdělit do sloupců dle počtu jader -1 a zpracovávat po řádku. Na to jsem nějaký skript na webu viděl, ale nevím jak na to. Nebo prostřednictvím toho paralelu nebo xargs.

Poradí někdo, jak docílit paralelního zpracování s větší prioritou zpracování pro velké soubory?


adsfasdfasdfasdf

Re:Paralelní zpracování souboru
« Odpověď #1 kdy: 21. 02. 2018, 13:11:43 »
ja bych se s tim vubec tak slozite nesral.
udelej si vypis (obrazkovych) souboru s vystupem do textoveho souboru: ls *.jpg > soubory,txt

soubor.txt rucne rozsekej na x kusu, podle toho kolik mas jader na tolik souboru: soubor1.txt, soubor2.txt.....souborX.txt

udelej si shel skript, ktery projizdi textovy soubor a z nazvu souboru (obrazku) v souborN.txt projedes fajly a zpracujes obrazky.

spustis skript x-krat:

./zpracovani soubor1.txt &> /dev/null &
./zpracovani soubor2.txt &> /dev/null &
./zpracovani souborX.txt &> /dev/null &

a nemusim vymyslet paralelni kraviny.
na prioritizaci kdyz zpracovavat male nebo velke obrazky se taky vyprdni. az ty skripty dojedou, tak dojedou.


adsfasdfasdfasdf

Re:Paralelní zpracování souboru
« Odpověď #2 kdy: 21. 02. 2018, 13:13:21 »
ja jsem si takhle jednoduse kdysi v praveku na pocitacovem clusteru graboval cd a wav do mp3.

Re:Paralelní zpracování souboru
« Odpověď #3 kdy: 21. 02. 2018, 13:14:32 »
Udělal bych to pomocí nástroje
Kód: [Vybrat]
make. Příkladů musí být na internetu tuny, umí i paralelní zpracování.
Předpokladem je, že optimalizované verze budou v jiném adresáři (nebo budou odlišené názvem).

beer

  • *****
  • 729
    • Zobrazit profil
Re:Paralelní zpracování souboru
« Odpověď #4 kdy: 21. 02. 2018, 13:39:45 »
Udělal bych to pomocí nástroje
Kód: [Vybrat]
make. Příkladů musí být na internetu tuny, umí i paralelní zpracování.
Předpokladem je, že optimalizované verze budou v jiném adresáři (nebo budou odlišené názvem).

Ten předpoklad na mém malém web serveru nelze splnit. Uživatel nahraje obrázek, wordpress z toho obrázku udělá x dalších obrázků - například:

uživatel nahraje
centruminvestic.cz/wp-content/uploads/2018/02/electrum-ltc.jpg

a wordpress udělá:














Navíc kdyby se optimalizovalo do jiné složky, nezobrazoval by se na webu optimalizovaný obrázek. Rovněž je potřeba na serveru šetřit místem.

ja bych se s tim vubec tak slozite nesral.
udelej si vypis (obrazkovych) souboru s vystupem do textoveho souboru: ls *.jpg > soubory,txt

soubor.txt rucne rozsekej na x kusu, podle toho kolik mas jader na tolik souboru: soubor1.txt, soubor2.txt.....souborX.txt

udelej si shel skript, ktery projizdi textovy soubor a z nazvu souboru (obrazku) v souborN.txt projedes fajly a zpracujes obrazky.

spustis skript x-krat:

./zpracovani soubor1.txt &> /dev/null &
./zpracovani soubor2.txt &> /dev/null &
./zpracovani souborX.txt &> /dev/null &

a nemusim vymyslet paralelni kraviny.
na prioritizaci kdyz zpracovavat male nebo velke obrazky se taky vyprdni. az ty skripty dojedou, tak dojedou.



Je to na webserveru, kde to script spouštím cronem. To ruční rozsekání je pro mne problém. Dejme tomu, že tam mám 4 jádra a chtěl bych tedy vždy spouštět 3x.


beer

  • *****
  • 729
    • Zobrazit profil
Re:Paralelní zpracování souboru
« Odpověď #5 kdy: 21. 02. 2018, 13:46:38 »
Udělal bych to pomocí nástroje
Kód: [Vybrat]
make. Příkladů musí být na internetu tuny, umí i paralelní zpracování.
Předpokladem je, že optimalizované verze budou v jiném adresáři (nebo budou odlišené názvem).

Mrknu na to, není to ale kanón na vrabce? A makem lze soubor po řádcích rozdělit na stejně velké části?

Jano

Re:Paralelní zpracování souboru
« Odpověď #6 kdy: 21. 02. 2018, 14:32:34 »
Skus pozriet aj https://ninja-build.org/
Na tej stranke je aj zoznam generatorov konfigurakov (napr. kniznica pre python).
Cize napises subor build.ninja, kde budu napisane pravidla ako sa optimalizuju obrazky, a zoznam obrazkov,
a on ti to pospusta paralelne (bud mu povies kolko jadier alebo si tipne sam).

beer

  • *****
  • 729
    • Zobrazit profil
Re:Paralelní zpracování souboru
« Odpověď #7 kdy: 21. 02. 2018, 14:50:36 »
Vypadá to zajímavě, ale asi další kanón na vrabce. Ono se ti to řekne jednoduše, napíšeš si soubor build.ninja :-).

Rád bych šel cestou vrstvení standardních jednoúčelových nástrojů, aby to bylo čitelné pro mne i pro ostatní. Spočítání řádků přes wc, spočítání kolik odříznout kam přes dc, a pak případně použít head, tail či sed na vytvoření 3 různých front a & je hodit na pozadí.

Zkusím metodou pokus omyl :-).
« Poslední změna: 21. 02. 2018, 14:53:54 od beer »

beer

  • *****
  • 729
    • Zobrazit profil
Re:Paralelní zpracování souboru
« Odpověď #8 kdy: 21. 02. 2018, 15:52:46 »
Nejjednodušší by bylo asi použití xargs, ale neumím to

zkusil jsem nahradit
Kód: [Vybrat]
while read line
do
printf "%s\n" "$line"
jpeg-recompress -q medium -l 128 -a -c -m smallfry "$(printf "%s\n" "$line")" "$(printf "%s\n" "$line")"
done < "$jpgfronta" &

tímto:
Kód: [Vybrat]
while read line
do
printf "%s\n" "$line"
"$(printf "%s\n" "$line")" "$(printf "%s\n" "$line")" | xargs --max-args=1 --max-procs=3 jpeg-recompress -q medium -l 128 -a -c -m smallfry
done < "$jpgfronta"

Ale mám tam nějakou chybu, obrázky to spouští jako spustitelné soubory a nepředává to cesty.

nalogmulti

Re:Paralelní zpracování souboru
« Odpověď #9 kdy: 21. 02. 2018, 17:01:25 »
A co třeba jen tevřít obrázky (případně přes search parametricky najít/filtrovat) v xnview a dát hromadnou konverzi?Mám ocit, že program nevyužívá jádra CPU. Případně Zoner Photo studio, zdarma

ja jsem si takhle jednoduse kdysi v praveku na pocitacovem clusteru graboval cd a wav do mp3.
Jakože jednotlivé thready ripovaly jednotlivé skladby?

beer

  • *****
  • 729
    • Zobrazit profil
Re:Paralelní zpracování souboru
« Odpověď #10 kdy: 21. 02. 2018, 17:07:04 »
A co třeba jen tevřít obrázky (případně přes search parametricky najít/filtrovat) v xnview a dát hromadnou konverzi?Mám ocit, že program nevyužívá jádra CPU. Případně Zoner Photo studio, zdarma

Používám Debian a Ubuntu. Na serveru nemám grafické prostředí.

ja jsem si takhle jednoduse kdysi v praveku na pocitacovem clusteru graboval cd a wav do mp3.
Jakože jednotlivé thready ripovaly jednotlivé skladby?
Nemůžu mluvit za adsfasdfasdfasd, ale řekl bych, že určitě takhle ne, laser bývá v mechanikách jen jeden. Spíše rippování do wavu v jednom vláknu a paralelní konverze všech wavů potom do komprimovaného formátu.

trubicoid2

Re:Paralelní zpracování souboru
« Odpověď #11 kdy: 21. 02. 2018, 17:23:50 »
Nejjednodušší by bylo asi použití xargs, ale neumím to

zkusil jsem nahradit
Kód: [Vybrat]
while read line
do
printf "%s\n" "$line"
jpeg-recompress -q medium -l 128 -a -c -m smallfry "$(printf "%s\n" "$line")" "$(printf "%s\n" "$line")"
done < "$jpgfronta" &

tímto:
Kód: [Vybrat]
while read line
do
printf "%s\n" "$line"
"$(printf "%s\n" "$line")" "$(printf "%s\n" "$line")" | xargs --max-args=1 --max-procs=3 jpeg-recompress -q medium -l 128 -a -c -m smallfry
done < "$jpgfronta"

Ale mám tam nějakou chybu, obrázky to spouští jako spustitelné soubory a nepředává to cesty.

ten jpeg-recompress žere dva stejný argumenty?

přes rouru pošleš jen jeden a pak xargs -I{} a použiješ {} tam, kde chceš ty argumenty

další možnost je gnu parallel, ale xargs toto zvládne dobře a je všude

beer

  • *****
  • 729
    • Zobrazit profil
Re:Paralelní zpracování souboru
« Odpověď #12 kdy: 21. 02. 2018, 17:29:54 »
žere, jsou povinné, zdrojový a cílový soubor. Když je to stejné, tak se optimalizuje soubor za běhu a zapíše se změna jen v případě, že soubor nebyl již optimalizovaný předtím, jpeg-recompress to řeší přidáním poznámky do metadat a při dalším spuštění nad stejným souborem soubor jednoduše přeskočí. Na rozdíl od optipng, to je hrozná brzda, která se snaží optimalizovat již optimalizované.

Vyzkouším, díky

Re:Paralelní zpracování souboru
« Odpověď #13 kdy: 21. 02. 2018, 19:43:20 »
a co kdybys proste misto GD pouzil ve WP imagick pro generovani nahledu a dal mu patricne parametry?
Děkuji za možnost editace příspěvku.

Re:Paralelní zpracování souboru
« Odpověď #14 kdy: 21. 02. 2018, 20:20:11 »
Udělal bych to pomocí nástroje
Kód: [Vybrat]
make. Příkladů musí být na internetu tuny, umí i paralelní zpracování.
Předpokladem je, že optimalizované verze budou v jiném adresáři (nebo budou odlišené názvem).

Ten předpoklad na mém malém web serveru nelze splnit. Uživatel nahraje obrázek, wordpress z toho obrázku udělá x dalších obrázků - například:

Můžete udělat nějaký „značkovací“ soubor. Dejme tomu, že obrázek bude třeba IMG_001.JPG, vy ho zoptimalizujete a uděláte soubor např. IMG_001.DONE, podle kterého pak make sám pozná, že už nemá na IMG_001.JPG sahat, pokud není JPG novější než DONE.

Kanón na vrabce to asi není, make je přesně ten jednoúčelový nástroj, který dělá dobře, co má:

Kód: [Vybrat]
# Makefile:

SRCDIR   := .
SRCFILES := $(wildcard $(SRCDIR)/*.jpg)
TRGFILES := $(patsubst $(SRCDIR)/%.jpg,$(SRCDIR)/%.done,$(SRCFILES))

all: $(SRCFILES) $(TRGFILES)
#   @echo "Make $@: from: $?";

%.done : %.jpg
    @echo "Make: $@ from: $?";
    @echo "*** Here you should optimalize: $? ***"                                                                                                           
    @touch $@;

clean:
    @rm -vf $(TRGFILES);

#eof

Použití:

Kód: [Vybrat]
make clean # odstranit .done soubory
make all # zpracovat obrázky
make all -j 3 # toto by mělo spustit 3 paralelní úlohy