Processamento Paralelo com xargs

Com processadores multi-core semi-parados na maior parte das nossas tarefas e com a necessidade de processar grandes quantidades de informação / ficheiros é importante aproveitar toda a potencialidade de todos os núcleos.

Nos sistemas Unix (neste caso testei num sistema Linux com a distro Ubuntu) é possível separar uma tarefa em vários processos de forma a que a tarefa seja distribuida por mais que um núcleo do processador (no caso dos processadores multi-core) e por vários processos (jobs) que podem ser executados em simultâneo não dependendo que o primeiro acabe para executar o segundo podendo ter vários a correr ao mesmo tempo aumentando assim a performance da acção.

Este comando suporta a opção -P com a qual podemos especificar a quantidade de processos (jobs) a correr em paralelo.

$ man xargs
(...)
 --max-procs=max-procs
-P max-procs
Run  up  to max-procs processes at a time; the default is 1.
If max-procs is 0, xargs will run as many processes as possible  at a  time.
Use the -n option with -P; otherwise chances are that only one exec will be done.
(...)

Exemplo de Utilização

$ ls . | xargs -P 0 -i -t cp -R {} ../novo/

Decompondo o Exemplo

Listagem dos ficheiros da pasta

$ ls .

Xargs

xargs -P 0 -i -t

“-P 0” utiliza o número máximo de processos
“-t” verbose mode activo

Cópia

cp -R {} ../novo/

“-R” copia de forma recursiva as pastas existentes
“{}” existe devido ao parâmetro “-i” do comando xargs utilizado, que corresponde a cada ficheiro/pasta que queremos copiar
“../novo” pasta de destino

Mais exemplos

Apagar todos os ficheiros com a extensão pdf

find ./ -name "*.pdf" | xargs -t -Istr rm str

Converter ficheiros pdf (.pdf) para ficheiros de texto simples (.txt)

find ./ -name "*.pdf" | xargs -Istr pdftotext str

Nestes exemplos podem acrescentar sempre a opção “-P x” em que x é o valor de processos que querem a correr em paralelo, em algumas situações permite-nos aumentar a performance do processamento através da resolução de tarefas em paralelo como veremos a seguir.

Testes de Performance

:~/teste$ ls
teste1  teste2
~/teste$ ls teste1/ | wc
33      58    1036
~/teste$ ls teste2/ | wc
33      58    1036

~/teste$ time find ./teste1/ -name "*.pdf" | xargs -Istr pdftotext str
real	1m9.805s
user	0m44.795s
sys	0m6.564s

~/teste$ time find ./teste2/ -name "*.pdf" | xargs -P 6 -Istr pdftotext str
real	0m39.911s
user	0m44.523s
sys	0m6.304s

Utilizando exactamente os mesmos ficheiros vemos alguma diferença a executar a mesma operação com e sem processamento distribuído da tarefa, que é realizada por diversos processos executados em paralelo.

~/teste$ time find ./teste1/ -name "*.pdf" | xargs -Istr rm str
real	0m0.296s
user	0m0.060s
sys	0m0.088s

~/teste$ time find ./teste2/ -name "*.pdf" | xargs -P 6 -Istr rm str
real	0m0.163s
user	0m0.060s
sys	0m0.084s

Novamente podemos verificar um aumento na performance das acções com o processamento em paralelo.

Outras utilizações

Além destas tarefas que foram mostradas em cima digamos, do dia-a-dia de qualquer utilizador de um sistema Unix que tenha descoberto as maravilhas da consola, podem ser destacadas utilizações mais direccionadas a áreas de trabalho:

  • utilização do xargs em conjunto com o ping para detectar vários hosts simultaneamente diminuindo o tempo de espera para grandes pesquisas
  • utilização do xargs em conjunto com o nmap. O nmap nos scans não utiliza muita bandwidth para não ser detectado e então podemos fazer scan a mais que um host em simultâneo aproveitando as capacidades da ligação e da máquina
  • conversão de discografias completas ou de albuns inteiros de fotos

Mais ideias diferentes?

Man Pages

$ man cp
$ man rm
$ man xargs
$ man ls
$ man find

1 comment

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.