Atualmente estou tendo problemas para dd
invocar um arquivo esparso como input( if
) e um arquivo como output( 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) (100% de 1 núcleo), então estou me perguntando se é possível paralelizar dd
. eu estive
- olhando para
info dd
eman dd
parece haver uma função integrada na versão do corutils 8.23 - verificando
sgp_dd
osg3-utils
pacote (sem entender se ele atende às minhas necessidades), mas parece não ser capaz de lidar com arquivos esparsos dcfldd
não parece ter recursos de paralelização
Até onde sei
- uma versão/fork aprimorada com manipulação interna de partes do programa em vários threads (evita mudanças de contexto que prejudicam o desempenho de E/S) é preferível a
- uma solução com GNU
parallel
rodando 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 Linux 3.13 e manipular imagens de disco de arquivos esparsos com ele em qualquer sistema de arquivos que suporte arquivos esparsos (pelo menos a solução não deve estar vinculada a um sistema de arquivos específico).
Antecedentes: Estou tentando criar uma cópia de um arquivo esparso de 11 TB (contendo cerca de 2 TB de dados) em um zfs (versão instável do zfsonlinux 0.6.4, possivelmente com bugs e a causa do gargalo da CPU (eventualmente pesquisa lenta de buracos)). Isso não deve mudar nada na questão de como paralelizar o dd (de uma forma muito genérica).
Responder1
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.
Responder2
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 particionar logicamente o arquivo em quatro pedaços 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, portanto o count=
parâmetro não é estritamente necessário.