¿Cómo paralelizar dd?

¿Cómo paralelizar dd?

Actualmente tengo problemas al ddinvocar con un archivo disperso como entrada ( if) y un archivo como salida ( of) con conv=sparse. ddParece estar usando Intel(R) Core(TM) i7-3632QM CPU @ 2.20GHzsolo un núcleo de la CPU (4 núcleos + 4 Intel Hyperthreads) (100% de 1 núcleo), por lo que me he estado preguntando si es posible paralelizar dd. He estado

  • mirando info ddy man ddparece haber una función incorporada en la versión de corutils 8.23
  • comprobando sgp_dddesde sg3-utilsel paquete (sin entender si se adapta a mis necesidades), pero no parece ser capaz de manejar archivos dispersos
  • dcflddno parece tener capacidades de paralelización

hasta donde se

  • Se prefiere una versión/bifurcación mejorada con manejo interno de partes del programa en múltiples subprocesos (evite cambios de contexto que afecten el rendimiento de E/S) a
  • parallelSe prefiere una solución con GNU ejecutándose localmente a
  • un fragmento de código personalizado (posiblemente no probado)

¿Cómo evitar que la CPU sea el cuello de botella de una operación intensiva de E/S? Me gustaría ejecutar el comando en Ubuntu 14.04 con Linux 3.13 y manejar imágenes de disco de archivos dispersos en cualquier sistema de archivos que admita archivos dispersos (al menos la solución no debe estar vinculada a un sistema de archivos específico).

Antecedentes: estoy intentando crear una copia de un archivo disperso de 11 TB (que contiene aproximadamente 2 TB de datos) en un zfs (versión inestable de zfsonlinux 0.6.4, posiblemente con errores y la causa del cuello de botella de la CPU (eventualmente, búsqueda lenta de agujeros)). Eso no debería cambiar nada en cuanto a la cuestión de cómo paralelizar dd (de una manera muy genérica).

Respuesta1

Probado en 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

Probablemente necesites ajustar 1000.

Respuesta2

Próximamente un fragmento de código personalizado y no probado:

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

Esto debería dividir lógicamente el archivo en cuatro fragmentos de 3 TB y procesarlos en paralelo. ( skip=salta los bloques de entrada; seek=busca los bloques de salida). El cuarto comando, por supuesto, leerá hasta el final del archivo antiguo, por lo que el count=parámetro no es estrictamente necesario.

información relacionada