Como paralelizar dd?

5

Atualmente estou tendo problemas com dd chamado com um arquivo esparso como entrada ( if ) e um arquivo como saída ( of ) com conv=sparse . dd parece estar usando apenas um núcleo da CPU ( Intel(R) Core(TM) i7-3632QM CPU @ 2.20GHz 4 núcleos + 4 Intel Hyperthreads) apenas (100% de 1 núcleo), então estou pensando se é possível paralelizar dd . Eu estive

  • pesquisando info dd e man dd e parece haver uma função incorporada na versão do corutils 8.23
  • verificando sgp_dd de sg3-utils package (sem entender se isso atende às minhas necessidades), mas não parece conseguir lidar com arquivos esparsos
  • dcfldd não parece ter recursos de paralelização

AFAIK

  • uma versão / fork aprimorada com manipulação interna de partes do programa em vários encadeamentos (evite alterações no contexto eliminando o desempenho de E / S) é preferível a
  • uma solução com o GNU parallel sendo executado localmente é preferível a
  • um sniplet de código personalizado (possivelmente não testado)

Como evitar que a CPU seja o gargalo de uma operação intensiva de E / S? Eu gostaria de executar o comando no Ubuntu 14.04 com o Linux 3.13 e lidar com imagens esparsas de disco com ele em qualquer sistema de arquivos que suporte arquivos esparsos (pelo menos a solução não deveria estar vinculada a um sistema de arquivos específico).

Antecedentes: Estou tentando criar uma cópia do arquivo esparso de 11TB (contendo cerca de 2TB de dados) em um zfs (zfsonlinux 0.6.4 instável, possivelmente com bugs e a causa do gargalo da CPU (eventualmente busca lenta)) . Isso não deve mudar nada para a questão de como paralelizar dd (de uma maneira muito genérica).

    
por Karl Richter 10.10.2014 / 22:31

2 respostas

2

Um sniplet de código personalizado e não testado está chegando:

dd if=oldf conv=sparse bs=1k                 count=3000000000                 of=newf &
dd if=oldf conv=sparse bs=1k skip=3000000000 count=3000000000 seek=3000000000 of=newf &
dd if=oldf conv=sparse bs=1k skip=6000000000 count=3000000000 seek=6000000000 of=newf &
dd if=oldf conv=sparse bs=1k skip=9000000000 count=3000000000 seek=9000000000 of=newf &
wait

Isso deve dividir logicamente o arquivo em quatro blocos de 3 TB e processá-los em paralelo. ( skip= pula os blocos de entrada; seek= procura os blocos de saída.) O quarto comando irá, é claro, ler até o final do arquivo antigo, então o parâmetro count= não é estritamente necessário.

    
por 10.10.2014 / 23:58
2

Testado no Bash:

INFILE=in
seq 0 1000 $(('stat --format %s $INFILE' /100000 )) |
  parallel -k dd if=$INFILE bs=100000 skip={} conv=sparse seek={} count=1000 of=out

Você provavelmente precisará ajustar 1000.

    
por 11.10.2014 / 10:32