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?
1 comment