¿La opción "bs" en "dd" realmente mejora la velocidad?

58

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 ):

ingrese la descripción de la imagen aquí

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
Damiano Verzulli
fuente
11
Lo que sería realmente bueno es tener una bs=autofunción ddque detecte y use el parámetro bs óptimo del dispositivo.
44
Lo que sería extremadamente bueno es un gráfico de varios bstamañ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.
MDMoore313
2
@BigHomie: pensé en proporcionar un gráfico pero ... hay varios problemas de "escala". Probablemente necesitaría una escala logarítmica en ambos ejes y ... mientras pensaba en esto, pensé que no era un problema fácil (y rápido) de resolver. Entonces cambié a la versión de "tabla". En cuanto a "... 15 docenas de bloques de código", quería que todos tuvieran la oportunidad de verificar "números en bruto", para evitar cualquier interferencia (personal, mía).
Damiano Verzulli
1
@DamianoVerzulli, la mesa es genial, por favor ignora mi discurso, te di un voto positivo por probar nuestras supersticiones de todos modos, y sé de primera mano que jugar con el tamaño del byte alterará la velocidad, también podría ponerlo en una respuesta.
MDMoore313
1
@warren - para obtener 4G también puedes hacerlo bs=8k count=512Ko bs=1M count=4Kno recuerdo poderes de 2 pasados ​​65536
usuario313114

Respuestas:

24

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=1Mque al usar bs=4ko 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 dduna SIGUSR1señal al proceso para que emita un informe de estado y pueda ver cómo va.

✗ killall -SIGUSR1 dd
1811+1 records in
1811+1 records out
1899528192 bytes (1.9 GB, 1.8 GiB) copied, 468.633 s, 4.1 MB/s
usuario313114
fuente
Copia de Macbook Pro Retina 2014 a memoria USB3 con una calificación de 90 MB / s de escritura: $ sudo dd if=~/Downloads/Qubes-R4.0-rc4-x86_64.iso of=/dev/rdisk2 status=progressmuestra 6140928 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=progressespectáculos4558159872 bytes (4.6 GB, 4.2 GiB) copied, 54 s, 84.4 MB/s
Eric Duncan
9

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 sdbhay un disco de interés:

# grep sdb /proc/diskstats
8      16 sdb 767 713 11834 6968 13710 6808 12970792 6846477 0 76967 6853359
...
# dd if=/dev/sdb of=/dev/null bs=1 count=512
512+0 records in
512+0 records out
512 bytes (512 B) copied, 0.0371715 s, 13.8 kB/s
# grep sedb /proc/diskstats
8      16 sdb 768 713 11834 6968 13710 6808 12970792 6846477 0 76967 6853359
...

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:

  • Al leer con el almacenamiento en caché (el valor predeterminado), una página es de 4k. Llenar una página con <4k lecturas es más complicado que mantener la lectura y el tamaño de página iguales.
  • La mayoría de los tamaños de bloque del sistema de archivos están configurados en 4k.
  • No es un número lo suficientemente pequeño (tal vez para SSDs ahora es sin embargo) como para causar una sobrecarga de syscall pero no un número lo suficientemente grande como para consumir mucha memoria.
Matthew Ife
fuente