De vez en cuando, me dicen que para aumentar la velocidad de un "dd" debo elegir cuidadosamente un "tamaño de bloque" adecuado.
Incluso aquí, en ServerFault, alguien más escribió que " ... el tamaño de bloque óptimo depende del hardware ... " (iain) o " ... el tamaño perfecto dependerá de su bus de sistema, controlador de disco duro, la unidad en particular en sí, y los controladores para cada uno de esos ... " (Chris-s)
Como mi sentimiento era un poco diferente ( BTW: pensé que el tiempo necesario para ajustar profundamente el parámetro bs era mucho mayor que la ganancia recibida, en términos de ahorro de tiempo, y que el valor predeterminado era razonable ), hoy solo fui a través de algunos puntos de referencia rápidos y sucios.
Para disminuir las influencias externas, decidí leer:
- desde una tarjeta MMC externa
- desde una partición interna
y:
- con sistemas de archivos relacionados desmontados
- enviando la salida a / dev / null para evitar problemas relacionados con la "velocidad de escritura";
- evitando algunos problemas básicos de almacenamiento en caché de HDD, al menos cuando se trata de HDD.
En la siguiente tabla, he informado mis hallazgos, leyendo 1 GB de datos con diferentes valores de "bs" ( puede encontrar los números sin formato al final de este mensaje ):
Básicamente se deduce que:
MMC: con un bs = 4 (¡sí! 4 bytes), alcancé un rendimiento de 12MB / s. A valores no tan distantes wrt al máximo 14.2 / 14.3 que obtuve de bs = 5 y superior;
HDD: con un bs = 10 llegué a 30 MB / s. Seguramente más bajo que el 95.3 MB obtenido con el valor predeterminado bs = 512 pero ... también significativo.
Además, estaba muy claro que el tiempo sys de la CPU era inversamente proporcional al valor bs (pero esto suena razonable, ya que cuanto más bajo es bs, mayor es el número de llamadas sys generadas por dd).
Habiendo dicho todo lo anterior, ahora la pregunta: ¿alguien puede explicar (un pirata informático del núcleo) cuáles son los principales componentes / sistemas involucrados en dicho rendimiento y si realmente vale la pena el esfuerzo de especificar un bs más alto que el predeterminado?
Caso MMC - números sin procesar
bs = 1M
root@iMac-Chiara:/tmp# time dd if=/dev/sdc of=/dev/null bs=1M count=1000
1000+0 record dentro
1000+0 record fuori
1048576000 byte (1,0 GB) copiati, 74,1239 s, 14,1 MB/s
real 1m14.126s
user 0m0.008s
sys 0m1.588s
bs = 1k
root@iMac-Chiara:/tmp# time dd if=/dev/sdc of=/dev/null bs=1k count=1000000
1000000+0 record dentro
1000000+0 record fuori
1024000000 byte (1,0 GB) copiati, 72,7795 s, 14,1 MB/s
real 1m12.782s
user 0m0.244s
sys 0m2.092s
bs = 512
root@iMac-Chiara:/tmp# time dd if=/dev/sdc of=/dev/null bs=512 count=2000000
2000000+0 record dentro
2000000+0 record fuori
1024000000 byte (1,0 GB) copiati, 72,867 s, 14,1 MB/s
real 1m12.869s
user 0m0.324s
sys 0m2.620s
bs = 10
root@iMac-Chiara:/tmp# time dd if=/dev/sdc of=/dev/null bs=10 count=100000000
100000000+0 record dentro
100000000+0 record fuori
1000000000 byte (1,0 GB) copiati, 70,1662 s, 14,3 MB/s
real 1m10.169s
user 0m6.272s
sys 0m28.712s
bs = 5
root@iMac-Chiara:/tmp# time dd if=/dev/sdc of=/dev/null bs=5 count=200000000
200000000+0 record dentro
200000000+0 record fuori
1000000000 byte (1,0 GB) copiati, 70,415 s, 14,2 MB/s
real 1m10.417s
user 0m11.604s
sys 0m55.984s
bs = 4
root@iMac-Chiara:/tmp# time dd if=/dev/sdc of=/dev/null bs=4 count=250000000
250000000+0 record dentro
250000000+0 record fuori
1000000000 byte (1,0 GB) copiati, 80,9114 s, 12,4 MB/s
real 1m20.914s
user 0m14.436s
sys 1m6.236s
bs = 2
root@iMac-Chiara:/tmp# time dd if=/dev/sdc of=/dev/null bs=2 count=500000000
500000000+0 record dentro
500000000+0 record fuori
1000000000 byte (1,0 GB) copiati, 161,974 s, 6,2 MB/s
real 2m41.976s
user 0m28.220s
sys 2m13.292s
bs = 1
root@iMac-Chiara:/tmp# time dd if=/dev/sdc of=/dev/null bs=1 count=1000000000
1000000000+0 record dentro
1000000000+0 record fuori
1000000000 byte (1,0 GB) copiati, 325,316 s, 3,1 MB/s
real 5m25.318s
user 0m56.212s
sys 4m28.176s
HDD case - números brutos
bs = 1
root@iMac-Chiara:/tmp# time dd if=/dev/sda3 of=/dev/null bs=1 count=1000000000
1000000000+0 record dentro
1000000000+0 record fuori
1000000000 byte (1,0 GB) copiati, 341,461 s, 2,9 MB/s
real 5m41.463s
user 0m56.000s
sys 4m44.340s
bs = 2
root@iMac-Chiara:/tmp# time dd if=/dev/sda3 of=/dev/null bs=2 count=500000000
500000000+0 record dentro
500000000+0 record fuori
1000000000 byte (1,0 GB) copiati, 164,072 s, 6,1 MB/s
real 2m44.074s
user 0m28.584s
sys 2m14.628s
bs = 4
root@iMac-Chiara:/tmp# time dd if=/dev/sda3 of=/dev/null bs=4 count=250000000
250000000+0 record dentro
250000000+0 record fuori
1000000000 byte (1,0 GB) copiati, 81,471 s, 12,3 MB/s
real 1m21.473s
user 0m14.824s
sys 1m6.416s
bs = 5
root@iMac-Chiara:/tmp# time dd if=/dev/sda3 of=/dev/null bs=5 count=200000000
200000000+0 record dentro
200000000+0 record fuori
1000000000 byte (1,0 GB) copiati, 66,0327 s, 15,1 MB/s
real 1m6.035s
user 0m11.176s
sys 0m54.668s
bs = 10
root@iMac-Chiara:/tmp# time dd if=/dev/sda3 of=/dev/null bs=10 count=100000000
100000000+0 record dentro
100000000+0 record fuori
1000000000 byte (1,0 GB) copiati, 33,4151 s, 29,9 MB/s
real 0m33.417s
user 0m5.692s
sys 0m27.624s
bs = 512 (compensando la lectura, para evitar el almacenamiento en caché)
root@iMac-Chiara:/tmp# time dd if=/dev/sda3 of=/dev/null bs=512 count=2000000 skip=6000000
2000000+0 record dentro
2000000+0 record fuori
1024000000 byte (1,0 GB) copiati, 10,7437 s, 95,3 MB/s
real 0m10.746s
user 0m0.360s
sys 0m2.428s
bs = 1k (compensando la lectura, para evitar el almacenamiento en caché)
root@iMac-Chiara:/tmp# time dd if=/dev/sda3 of=/dev/null bs=1k count=1000000 skip=6000000
1000000+0 record dentro
1000000+0 record fuori
1024000000 byte (1,0 GB) copiati, 10,6561 s, 96,1 MB/s
real 0m10.658s
user 0m0.164s
sys 0m1.772s
bs = 1k (compensando la lectura, para evitar el almacenamiento en caché)
root@iMac-Chiara:/tmp# time dd if=/dev/sda3 of=/dev/null bs=1M count=1000 skip=7000
1000+0 record dentro
1000+0 record fuori
1048576000 byte (1,0 GB) copiati, 10,7391 s, 97,6 MB/s
real 0m10.792s
user 0m0.008s
sys 0m1.144s
fuente
bs=auto
funcióndd
que detecte y use el parámetro bs óptimo del dispositivo.bs
tamaños trazados contra la velocidad en lugar de 15 docenas de bloques de código en una sola pregunta. Tomaría menos espacio y sería infinitamente más rápido de leer. Una imagen verdaderamente es vale más que thoursand palabras.bs=8k count=512K
obs=1M count=4K
no recuerdo poderes de 2 pasados 65536Respuestas:
Lo que has hecho es solo una prueba de velocidad de lectura. si realmente está copiando bloques a otro dispositivo, tiene pausas en la lectura mientras el otro dispositivo acepta los datos que desea escribir, cuando esto sucede, puede tener problemas de latencia rotacional en el dispositivo de lectura (si es un disco duro) y así a menudo es significativamente más rápido leer fragmentos de 1M del HDD a medida que te encuentras con la latencia rotacional con menos frecuencia de esa manera.
Sé que cuando copio discos duros obtengo una tasa más rápida al especificar
bs=1M
que al usarbs=4k
o el valor predeterminado. Estoy hablando de mejoras de velocidad del 30 al 300 por ciento. No hay necesidad de ajustarlo para obtener el mejor absoluto a menos que sea todo lo que haces todos los días. pero elegir algo mejor que el predeterminado puede reducir horas del tiempo de ejecución.Cuando lo esté utilizando de verdad, pruebe con algunos números diferentes y envíe
dd
unaSIGUSR1
señal al proceso para que emita un informe de estado y pueda ver cómo va.fuente
$ sudo dd if=~/Downloads/Qubes-R4.0-rc4-x86_64.iso of=/dev/rdisk2 status=progress
muestra6140928 bytes (6.1 MB, 5.9 MiB) copied, 23 s, 267 kB/s
. Lo cancelé porque me estaba tomando demasiado tiempo. Ahora especificando el tamaño de bytes:$ sudo dd if=~/Downloads/Qubes-R4.0-rc4-x86_64.iso of=/dev/rdisk2 bs=1M status=progress
espectáculos4558159872 bytes (4.6 GB, 4.2 GiB) copied, 54 s, 84.4 MB/s
Con respecto al disco duro interno, al menos, cuando está leyendo desde el dispositivo, la capa de bloque al menos tiene que recuperar un sector que es de 512 bytes.
Entonces, cuando maneja una lectura de 1 byte, realmente solo ha leído desde el disco en la recuperación de byte alineado por sector. Las 511 veces restantes son atendidas por caché.
Puede probar esto de la siguiente manera, en este ejemplo
sdb
hay un disco de interés:La cuarta columna (que cuenta las lecturas) indica que solo se produjo 1 lectura, a pesar de que solicitó lecturas de 1 byte. Este es el comportamiento esperado, ya que este dispositivo (un disco SATA 2) debe, como mínimo, devolver su tamaño de sector. El núcleo simplemente está almacenando en caché todo el sector.
El factor más importante en estas solicitudes de tamaño es la sobrecarga de emitir una llamada al sistema para una lectura o escritura. De hecho, emitir la llamada para <512 es ineficiente. Las lecturas muy grandes requieren menos llamadas al sistema a costa de que se use más memoria para hacerlo.
4096 es típicamente un número 'seguro' para leer porque:
fuente