Bash Paralelização de processos intensivos de CPU

2

tee encaminha seu stdin para cada arquivo especificado, enquanto pee faz o mesmo, mas para pipes. Esses programas enviam cada linha do seu stdin para cada arquivo / pipe especificado.

No entanto, eu estava procurando uma maneira de "load balance" o stdin para diferentes pipes, então uma linha é enviada para o primeiro pipe, outra para o segundo, etc. Também seria bom se o stdout do tubos são coletados em um fluxo também.

O caso de uso é uma simples paralelização de processos intensivos de CPU que funcionam linha a linha. Eu estava fazendo um sed em um arquivo de 14GB, e poderia ter rodado muito mais rápido se eu pudesse usar vários processos sed . O comando foi assim:

pv infile | sed 's/something//' > outfile

Para paralelizar, o melhor seria se o paralelo GNU suportasse essa funcionalidade como tal (criado a opção --demux-stdin ):

pv infile | parallel -u -j4 --demux-stdin "sed 's/something//'" > outfile

No entanto, não há nenhuma opção como esta e parallel sempre usa seu stdin como argumentos para o comando que invoca, como xargs . Então eu tentei isso, mas é irremediavelmente lento, e está claro o porquê:

pv infile | parallel -u -j4 "echo {} | sed 's/something//'" > outfile

Eu só queria saber se há outra maneira de fazer isso (menos de codificar isso). Se houvesse um "equilíbrio de carga" tee (vamos chamá-lo de lee ), eu poderia fazer isso:

pv infile | lee >(sed 's/something//' >> outfile) >(sed 's/something//' >> outfile) >(sed 's/something//' >> outfile) >(sed 's/something//' >> outfile)

Não é bonita, então eu definitivamente prefiro algo como a versão parallel , mas isso também funcionaria.

    
por ehsanul 14.01.2011 / 23:30

2 respostas

3

Estamos discutindo como implementar exatamente esse recurso na lista de discussão do GNU Parallel agora link

Sinta-se à vontade para participar: link

Um protótipo está pronto para testes: link

    
por 15.01.2011 / 01:10
0

Eu olharia para implementar isso em Perl com Parallel :: ForkManager . Você poderia fazer a divisão de linha no script e depois alimentar as linhas resultantes nos processos Parallel :: ForkManager. O uso do retorno de chamada run_on_finish para coletar a saída. Obviamente, para o seu exemplo de sed você poderia apenas fazer a operação de texto em perl e talvez usar algo como AnyEvent para lidar com o paralelismo.

    
por 15.01.2011 / 02:39

Tags