Estou usando xargs
para chamar um script python para processar cerca de 30 milhões de arquivos pequenos. Espero usar xargs
para paralelizar o processo. O comando que estou usando é:
find ./data -name "*.json" -print0 |
xargs -0 -I{} -P 40 python Convert.py {} > log.txt
Basicamente, Convert.py
lerá em um pequeno arquivo json (4kb), processará e gravará em outro arquivo de 4kb. Estou executando em um servidor com 40 núcleos de CPU. E nenhum outro processo intenso de CPU está em execução neste servidor.
Ao monitorar o htop (btw, existe outra boa maneira de monitorar o desempenho da CPU?), Acho que -P 40
não é tão rápido quanto o esperado. Às vezes, todos os núcleos congelam e diminuem quase para zero por 3-4 segundos e depois se recuperam para 60-70%. Então, tento diminuir o número de processos paralelos para -P 20-30
, mas ainda não é muito rápido. O comportamento ideal deve ser a aceleração linear. Alguma sugestão para o uso paralelo de xargs?
fonte
xargs -P
e>
está se abrindo para condições de corrida devido ao problema de meia linha gnu.org/software/parallel/… O uso do GNU Parallel não terá esse problema.Respostas:
Eu estaria disposto a apostar que seu problema é python . Você não disse que tipo de processamento está sendo feito em cada arquivo, mas supondo que você esteja apenas processando os dados na memória, o tempo de execução será dominado pela inicialização de 30 milhões de máquinas virtuais python (intérpretes).
Se você puder reestruturar seu programa python para obter uma lista de arquivos, em vez de apenas um, obterá uma enorme melhoria no desempenho. Você ainda pode usar xargs para melhorar ainda mais o desempenho. Por exemplo, 40 processos, cada um processando 1000 arquivos:
Isso não quer dizer que python seja uma linguagem ruim / lenta; simplesmente não é otimizado para o tempo de inicialização. Você verá isso em qualquer linguagem interpretada ou baseada em máquina virtual. Java, por exemplo, seria ainda pior. Se o seu programa fosse escrito em C, ainda haveria um custo para iniciar um processo separado do sistema operacional para lidar com cada arquivo, mas seria muito menor.
A partir daí, você pode se familiarizar
-P
para ver se consegue diminuir um pouco mais de velocidade, talvez aumentando o número de processos para aproveitar os processadores inativos enquanto os dados estão sendo lidos / gravados.fonte
Então, primeiro, considere as restrições:
Qual é a restrição em cada trabalho? Se for E / S, você provavelmente poderá executar vários trabalhos por núcleo de CPU até atingir o limite de E / S, mas se consumir muito CPU, será pior do que inútil executar mais trabalhos simultaneamente do que os núcleos de CPU.
O meu entendimento dessas coisas é que o GNU Parallel lhe daria melhor controle sobre a fila de trabalhos, etc.
Veja Paralelo GNU vs & (refiro-me ao plano de fundo) vs xargs -P para uma explicação mais detalhada de como os dois diferem.
fonte
Como outros disseram, verifique se você está vinculado à E / S. Além disso, a página de manual do xargs sugere o uso
-n
com-P
, você não menciona o número deConvert.py
processos que vê executando paralelamente.Como sugestão, se você estiver vinculado à E / S, tente usar um dispositivo de bloco SSD ou faça o processamento em um tmpfs (é claro, nesse caso, verifique se há memória suficiente, evitando a troca devido a tmpfs pressão (eu acho) e a sobrecarga de copiar os dados para ele em primeiro lugar).
fonte