Actualmente tengo problemas al dd
invocar con un archivo disperso como entrada ( if
) y un archivo como salida ( of
) con conv=sparse
. dd
Parece estar usando Intel(R) Core(TM) i7-3632QM CPU @ 2.20GHz
solo 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 dd
yman dd
parece haber una función incorporada en la versión de corutils 8.23 - comprobando
sgp_dd
desdesg3-utils
el paquete (sin entender si se adapta a mis necesidades), pero no parece ser capaz de manejar archivos dispersos dcfldd
no 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
parallel
Se 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.