¿Hay alguna manera de determinar el valor óptimo para el parámetro bs a dd?

71

En ocasiones, he visto comentarios en línea como "asegúrate de establecer 'bs =' porque el valor predeterminado tardará demasiado" y mis propias experiencias extremadamente poco científicas de "bueno, eso pareció tomar más tiempo que ese otro tiempo la semana pasada "parece confirmar eso. Entonces, cada vez que uso 'dd' (generalmente en el rango de 1-2 GB) me aseguro de especificar el parámetro de bytes. Aproximadamente la mitad del tiempo utilizo el valor especificado en la guía en línea desde la que copio; el resto del tiempo elegiré algún número que tenga sentido de la lista 'fdisk -l' para lo que supongo que es el medio más lento (por ejemplo, la tarjeta SD en la que estoy escribiendo).

Para una situación dada (tipo de medio, tamaño de bus o cualquier otra cosa importante), ¿hay alguna forma de determinar el "mejor" valor? ¿Es fácil de determinar? Si no, ¿hay una manera fácil de llegar al 90-95% del camino? ¿O es "simplemente elige algo más grande que 512", incluso la respuesta correcta?

He pensado probar el experimento yo mismo, pero (además de ser mucho trabajo) no estoy seguro de qué factores afectan la respuesta, por lo que no sé cómo diseñar un buen experimento.

drewbenn
fuente
escribir en el mismo medio de almacenamiento es diferente de escribir en un medio de almacenamiento diferente y requeriría diferentes configuraciones óptimas, hay muchas variables que serán diferentes para todos, dependiendo del tipo de dispositivo, velocidad, caché, etc. En mi máquina bs = 256M es óptimo.

Respuestas:

27

dddata de cuando era necesario traducir las viejas cintas de mainframe de IBM, y el tamaño del bloque tenía que coincidir con el utilizado para escribir la cinta o los bloques de datos se omitirían o truncarían. (Las cintas de 9 pistas eran delicadas. Me alegro de que hayan muerto hace mucho tiempo). En estos días, el tamaño del bloque debería ser un múltiplo del tamaño del sector del dispositivo (generalmente 4KB, pero en discos muy recientes puede ser mucho más grande y muy pequeño) las unidades pueden ser más pequeñas, pero 4KB es un punto medio razonable independientemente y cuanto más grande, mejor para el rendimiento. A menudo uso bloques de 1 MB con discos duros. (Tenemos mucho más memoria para tirar estos días también).

geekosaur
fuente
Los discos duros o los dispositivos de almacenamiento masivo USB tienen 512 o 4096 (más nuevos) bytes. Los medios flash de acceso directo y óptico son 2048 bytes. No puede salir mal con 4096 bytes.
LawrenceC
3
¿Por qué el tamaño de bloque del programa de copia debería tener algo que ver con las características del dispositivo subyacente (salvo las cintas)? El kernel realiza su propio almacenamiento en búfer (y, a veces, capta previamente) de todos modos.
Gilles 'SO- deja de ser malvado'
1
Para minimizar los tampones fraccionales; en general, las cosas se aceleran cuando se usan memorias intermedias alineadas porque el núcleo puede iniciar lecturas / escrituras de la memoria intermedia en el sector (o mejor, pista o cilindro, pero creo que las unidades modernas mienten sobre eso) y los límites de la memoria intermedia del núcleo, porque el núcleo no tiene para saltar cosas o leer cosas adicionales o administrar memorias intermedias parciales. Ciertamente, puede dejar que el núcleo se encargue de todo, pero si está copiando gigabytes de datos, ese trabajo adicional puede reducir considerablemente el tiempo de copia.
geekosaur
Usted (generalmente) debe incluir @Gillessi desea que se me notifique su respuesta al comentario, consulte ¿Cómo funcionan los comentarios @respuestas? . Desde que estaba pasando: el núcleo se ocupará de todo de todos modos. Su afirmación de que "ese trabajo adicional puede reducir el tiempo de copia considerablemente" no está de acuerdo con mis puntos de referencia, pero los diferentes sistemas pueden tener comportamientos diferentes, ¡así que por favor contribuya también con los tiempos!
Gilles 'SO- deja de ser malvado'
@Gilles: lo siento, te había confundido con el autor de la pregunta original.
geekosaur
60

Solo hay una forma de determinar el tamaño de bloque óptimo, y esa es una referencia. Acabo de hacer un punto de referencia rápido. La máquina de prueba es una PC con Debian GNU / Linux, con kernel 2.6.32 y coreutils 8.5. Ambos sistemas de archivos involucrados son ext3 en volúmenes LVM en una partición de disco duro. El archivo fuente es de 2GB (2040000kB para ser precisos). El almacenamiento en caché y el almacenamiento en búfer están habilitados. Antes de cada carrera, vacié el caché con sync; echo 1 >|/proc/sys/vm/drop_caches. Los tiempos de ejecución no incluyen una final syncpara vaciar los búferes; la última synctoma del orden de 1 segundo. Las sameejecuciones fueron copias en el mismo sistema de archivos; las diffejecuciones fueron copias a un sistema de archivos en un disco duro diferente. Por coherencia, los tiempos informados son los tiempos de reloj de pared obtenidos con eltimeutilidad, en segundos. Solo ejecuté cada comando una vez, así que no sé cuánta variación hay en el tiempo.

             same   diff
dd bs=64M    71.1   51.3
dd bs=1M     73.9   41.8
dd bs=4k     79.6   48.5
dd bs=512    85.3   48.9
cat          76.2   41.7
cp           77.8   45.3

Conclusión: un gran tamaño de bloque (varios megabytes) ayuda, pero no dramáticamente (mucho menos de lo que esperaba para copias de la misma unidad). Y caty cpno te va tan mal. Con estos números, no creo que ddvalga la pena molestarse. Ir con cat!

Gilles 'SO- deja de ser malvado'
fuente
Recomiendo que el OP haga su propia evaluación comparativa, pero de todos modos, ¡buena respuesta!
ninjalj
55
@Nikhil >|es el mismo que, >excepto que debajo set -o noclobber, el shell se quejará de que el archivo existe si lo usa >.
Gilles 'SO- deja de ser malvado'
2
@ Masi Sí, si quiero clonar un disco completo, lo usaré cat. ¿Por qué estás buscando una mejor manera? ¿Qué tiene de malo cat?
Gilles 'SO- deja de ser malvado'
55
@Masi catsimplemente copia su entrada a su salida. Si desea copiar desde medios poco confiables y omitir partes ilegibles o volver a intentarlo varias veces, ese es un problema diferente, para el cual ddrescuefunciona bastante bien.
Gilles 'SO- deja de ser malvado'
1
@sudo Puede obtener la cantidad de datos copiados lsof. La velocidad instantánea no es muy relevante con una copia de disco porque es uniforme, por lo que puede dividir los bytes transferidos por el tiempo transcurrido; si quieres algo mejor, puedes usarlo pv.
Gilles 'SO- deja de ser malvado'
8

Estoy de acuerdo con geekosaur en que el tamaño debe ser un múltiplo del tamaño del bloque, que a menudo es 4K.

Si desea encontrar el tamaño del bloque stat -c "%o" filenamees probablemente la opción más fácil.

Pero digamos que sí dd bs=4K, eso significa que sí read(4096); write(4096); read(4096); write(4096)...

Cada llamada al sistema implica un cambio de contexto, lo que implica una sobrecarga y, dependiendo del planificador de E / S, las lecturas con escrituras intercaladas podrían hacer que el disco realice muchas búsquedas. (Probablemente no sea un problema importante con el planificador de Linux, pero no obstante, algo en lo que pensar).

Entonces, si lo hace bs=8K, permite que el disco lea dos bloques a la vez, que probablemente estén muy juntos en el disco, antes de buscar otro lugar para hacer la escritura (o para dar servicio a E / S para otro proceso).

Por esa lógica, bs=16Kes aún mejor, etc.

Entonces, lo que me gustaría saber es si hay un límite superior donde el rendimiento comienza a empeorar, o si solo está limitado por la memoria.

Mikel
fuente
44
Perfil, no especules!
Gilles 'SO- deja de ser malvado'
1
La interfaz de programación de Linux está de acuerdo conmigo. Consulte el Capítulo 13: Almacenamiento de E / S de archivos
Mikel
44
Curiosamente, sus puntos de referencia sugieren que hay poco beneficio por encima de 4K.
Mikel
44
Además, aparentemente la ventana predeterminada de lectura anticipada del archivo es de 128 KB, por lo que ese valor puede ser beneficioso.
Mikel
66
Aquí tengo acceso a un RAID50 de 24 unidades, donde bs = 8K me da 197MB / s pero bs = 1M me da 2.2 GB / s, lo cual está cerca del rendimiento teórico del RAID. Entonces bs importa MUCHO. Sin embargo, usando bs = 10M solo obtengo 1.7GB / s. Por lo tanto, parece empeorar por encima de algún umbral, pero no estoy seguro de por qué.
Joseph Garvin el
5

Como dice Gilles, puede determinar el parámetro óptimo para la opción bs a dd mediante la evaluación comparativa. Sin embargo, esto plantea la pregunta: ¿cómo puede comparar convenientemente este parámetro?

Mi respuesta tentativa a esta pregunta es: use dd-opt , la utilidad en la que recientemente comencé a trabajar para resolver precisamente este problema :)

sampablokuper
fuente
1
¿Cuál es la sensibilidad de la salida? 90-95% o> 95%? No encuentro que puedas cambiarlo.
Léo Léopold Hertz 준영
1
@ Masi, me temo que no he trabajado dd-opten mucho tiempo. Sin embargo, es un software gratuito con licencia bajo AGPLv3 . ¡Entonces, siéntase libre de mejorarlo y evaluar su sensibilidad / precisión!
sampablokuper
0

Optimicé para sdcard reader usb2.0 que parece funcionar mejor bs=10M. Intenté 4k, hasta 16M, después de 8-10M no hubo mejora. Puede ver cómo se degrada la medición de la velocidad de transferencia ... muy probablemente debido a que carga las memorias intermedias en el dispositivo y luego espera a que el dispositivo se transfiera al medio real.

angstrom/sdcard# dd if=/dev/zero of=/dev/sdb bs=10M
123+0 records in
123+0 records out
1289748480 bytes (1.3 GB) copied, 21.4684 s, 60.1 MB/s
341+0 records in
341+0 records out
3575644160 bytes (3.6 GB) copied, 117.636 s, 30.4 MB/s
816+0 records in
816+0 records out
8556380160 bytes (8.6 GB) copied, 326.588 s, 26.2 MB/s
955+0 records in
955+0 records out
10013900800 bytes (10 GB) copied, 387.456 s, 25.8 MB/s
wwright
fuente