O paralelo GNU não divide o trabalho uniformemente

2

Meu entendimento é que a opção -X deve distribuir os argumentos uniformemente entre os trabalhos. No entanto, recebo uma distribuição muito distorcida:

user@host:/tmp/ptest$ count() {
>   echo $#
> }
user@host:/tmp/ptest$ export -f count

user@host:/tmp/ptest$ count *.jpg
5825
user@host:/tmp/ptest$ parallel -X count ::: *.jpg
5039
197
197
197
195

Curiosamente, usar apenas um subconjunto dos arquivos leva a uma distribuição uniforme de parâmetros:

user@host:/tmp/ptest$ count p129*.jpg
975
user@host:/tmp/ptest$ parallel -X count ::: p129*.jpg
244
244
244
243

user@host:/tmp/ptest$ count p12*.jpg
4007
user@host:/tmp/ptest$ parallel -X count ::: p12*.jpg
1002
1002
1002
1001

user@host:/tmp/ptest$ count p13*.jpg
1818
user@host:/tmp/ptest$ parallel -X count ::: p13*.jpg
455
455
455
453

Por que está errado no primeiro caso e como posso corrigi-lo?

    
por Zoltan 02.10.2018 / 08:18

1 resposta

3

-X é distribuído uniformemente quando atinge o EOF.

Então, no seu caso, ele preenche o buffer para uma linha de comando completa (nomes 5039) e inicia isso. Em seguida, ele lê outros 800 nomes até atingir o EOF. Isso não é suficiente para iniciar um trabalho completo, então eles são distribuídos entre os jobslots.

Veja a página 37 link

Isso é feito dessa forma para evitar a necessidade de ler todos os trabalhos com antecedência, pois todos os trabalhos podem não estar disponíveis (pense em tail -f file.names | parallel ... ).

Pode ser uma idéia melhor se o GNU Parallel ler nomes suficientes para preencher todos os jobslots antes de iniciar o próximo trabalho no modo -X , para que ele possa detectar o EOF anteriormente. Isso, no entanto, não foi implementado. Patch bem-vindo.

Uma solução alternativa é usar:

ls *.jpg |
  parallel --round --pipe -N1 parallel -Xj1 count

Não é possível produzir após cada trabalho, mas pode fazer uma saída linebuffered:

ls *.jpg |
  parallel --lb --round --pipe -N1 parallel --lb -Xj1 count

Se os nomes dos arquivos contiverem \ n:

printf '%s
ls *.jpg |
  parallel --round --pipe -N1 parallel -Xj1 count
' *.jpg | parallel --recend '
ls *.jpg |
  parallel --lb --round --pipe -N1 parallel --lb -Xj1 count
' --round --lb --pipe -N1 parallel -0Xj1 count
    
por 02.10.2018 / 10:54