EDIT: Para quem se depara com isso no futuro:
O Imagemagick usa uma biblioteca MP. É mais rápido usar os núcleos disponíveis se eles estiverem por perto, mas se você tiver trabalhos paralelos, isso é inútil.
Siga um destes procedimentos:
- faça seus trabalhos em série (com o Imagemagick no modo paralelo)
- defina MAGICK_THREAD_LIMIT = 1 para sua invocação do binário imagemagick em questão.
Ao fazer com que o Imagemagick use apenas um thread, ele diminui em 20-30% nos casos de teste, mas significa que posso executar um job por núcleo sem problemas, para um aumento significativo no desempenho.
Pergunta original:
Ao converter algumas imagens usando o ImageMagick, notei um efeito um pouco estranho. Usando xargs foi significativamente mais lento que um padrão para loop. Como os xargs limitados a um único processo devem agir como um loop for, eu testei isso e achei que fosse o mesmo.
Assim, temos essa demonstração.
- Quad core (AMD Athalon X4, 2,6 GHz)
- Trabalhando inteiramente em um tempfs (total de 16g ram; sem swap)
- Sem outras cargas principais
Resultados:
/media/ramdisk/img$ time for f in *.bmp; do echo $f ${f%bmp}png; done | xargs -n 2 -P 1 convert -auto-level
real 0m3.784s
user 0m2.240s
sys 0m0.230s
/media/ramdisk/img$ time for f in *.bmp; do echo $f ${f%bmp}png; done | xargs -n 2 -P 2 convert -auto-level
real 0m9.097s
user 0m28.020s
sys 0m0.910s
/media/ramdisk/img$ time for f in *.bmp; do echo $f ${f%bmp}png; done | xargs -n 2 -P 10 convert -auto-level
real 0m9.844s
user 0m33.200s
sys 0m1.270s
Alguém pode pensar em um motivo pelo qual a execução de duas instâncias desse programa leva mais que o dobro do tempo em tempo real e mais de dez vezes o tempo do processador para concluir a mesma tarefa? Depois desse hit inicial, mais processos não parecem ter um efeito tão significativo.
Eu pensei que poderia ter a ver com a busca de disco, então eu fiz esse teste inteiramente em memória RAM. Poderia ter algo a ver com o modo como o Convert funciona e ter mais de uma cópia de uma só vez significa que ele não pode usar o cache do processador com a mesma eficiência ou algo assim?
EDIT: Quando feito com arquivos de 1000x 769KB, o desempenho é o esperado. Interessante.
/media/ramdisk/img$ time for f in *.bmp; do echo $f ${f%bmp}png; done | xargs -n 2 -P 1 convert -auto-level
real 3m37.679s
user 5m6.980s
sys 0m6.340s
/media/ramdisk/img$ time for f in *.bmp; do echo $f ${f%bmp}png; done | xargs -n 2 -P 1 convert -auto-level
real 3m37.152s
user 5m6.140s
sys 0m6.530s
/media/ramdisk/img$ time for f in *.bmp; do echo $f ${f%bmp}png; done | xargs -n 2 -P 2 convert -auto-level
real 2m7.578s
user 5m35.410s
sys 0m6.050s
/media/ramdisk/img$ time for f in *.bmp; do echo $f ${f%bmp}png; done | xargs -n 2 -P 4 convert -auto-level
real 1m36.959s
user 5m48.900s
sys 0m6.350s
/media/ramdisk/img$ time for f in *.bmp; do echo $f ${f%bmp}png; done | xargs -n 2 -P 10 convert -auto-level
real 1m36.392s
user 5m54.840s
sys 0m5.650s