L'opzione "bs" in "dd" migliora davvero la velocità?


58

Ogni tanto mi viene detto che per aumentare la velocità di un "dd" dovrei scegliere con cura una "dimensione del blocco" corretta.

Anche qui, su ServerFault, qualcun altro ha scritto che " ... la dimensione ottimale del blocco dipende dall'hardware ... " (iain) o " ... la dimensione perfetta dipenderà dal bus di sistema, dal controller del disco rigido, dall'unità specifica stesso, e i driver per ciascuno di quei ... " (chris-s)

Dato che la mia sensazione era un po 'diversa ( BTW: ho pensato che il tempo necessario per mettere a punto il parametro bs fosse molto più alto del guadagno ricevuto, in termini di tempo risparmiato, e che il valore predefinito era ragionevole ), oggi sono andato attraverso alcuni benchmark rapidi e sporchi.

Al fine di ridurre le influenze esterne, ho deciso di leggere:

  • da una scheda MMC esterna
  • da una partizione interna

e:

  • con i relativi filesystem smontati
  • invio dell'output a / dev / null per evitare problemi relativi alla "velocità di scrittura";
  • evitando alcuni problemi di base della memorizzazione nella cache dell'HDD, almeno quando si tratta dell'HDD.

Nella tabella seguente, ho riportato i miei risultati, leggendo 1 GB di dati con valori diversi di "bs" ( è possibile trovare i numeri non elaborati alla fine di questo messaggio ):

inserisci qui la descrizione dell'immagine

Fondamentalmente emerge che:

  • MMC: con bs = 4 (sì! 4 byte), ho raggiunto un throughput di 12 MB / s. A valori non così distanti sono stati scritti al massimo 14,2 / 14,3 che ho ottenuto da bs = 5 e oltre;

  • HDD: con un bs = 10 ho raggiunto 30 MB / s. Sicuramente inferiore ai 95,3 MB ottenuti con il valore predefinito bs = 512 ma ... anche significativo.

Inoltre, era molto chiaro che il tempo di sistema della CPU era inversamente proporzionale al valore di bs (ma questo sembra ragionevole, poiché più basso è bs, maggiore è il numero di chiamate di sistema generate da dd).

Detto questo, ora la domanda: qualcuno può spiegare (un hacker del kernel?) Quali sono i principali componenti / sistemi coinvolti in tale throughput e se vale davvero la pena di specificare un bs superiore a quello predefinito?


Caso MMC - numeri grezzi

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

Custodia per HDD: numeri non elaborati

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 (offset della lettura, per evitare la memorizzazione nella cache)

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 (offset della lettura, per evitare la memorizzazione nella cache)

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 (offset della lettura, per evitare la memorizzazione nella cache)

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

11
Ciò che sarebbe davvero bello è avere una bs=autofunzione in ddgrado di rilevare e utilizzare il parametro bs ottimale dal dispositivo.

4
Ciò che sarebbe estremamente bello è un grafico di diverse bsdimensioni tracciato contro la velocità anziché 15 dozzine di blocchi di codice in una sola domanda. Richiederebbe meno spazio e sarebbe infinitamente più veloce da leggere. Un quadro veramente è vale più di thoursand parole.
MDMoore313,

2
@BigHomie - Ho pensato di fornire un grafico ma ... ci sono diversi problemi di "ridimensionamento". Avrebbe probabilmente bisogno di una scala logaritmica su entrambi gli assi e ... mentre pensavo a questo, ho pensato che non fosse un problema facile (e veloce) da risolvere. Quindi sono passato alla versione "table". Per quanto riguarda i "... 15 dozzine di blocchi di codice", volevo che tutti avessero la possibilità di controllare i "numeri non elaborati", per evitare qualsiasi interferenza (personale, mia).
Damiano Verzulli,

1
@DamianoVerzulli il tavolo è bello, per favore ignora la mia rabbia, ti ho dato un voto per dimostrare le nostre superstizioni comunque, e so in prima persona che giocherellare con la dimensione dei byte altererà la velocità, potrei anche inserirlo in una risposta.
MDMoore313,

1
@warren - per ottenere 4G puoi anche fare bs=8k count=512Ko bs=1M count=4Knon ricordo i poteri di 2 precedenti 65536
user313114

Risposte:


24

Quello che hai fatto è solo un test di velocità di lettura. se in realtà stai copiando i blocchi su un altro dispositivo hai delle pause nella lettura mentre l'altro dispositivo accetta i dati che vuoi scrivere, quando ciò accade puoi colpire i problemi di latenza di rotazione sul dispositivo di lettura (se si tratta di un disco rigido) e così spesso è significativamente più veloce leggere blocchi 1M dall'HDD quando si incontra la latenza rotazionale meno spesso in quel modo.

So che quando sto copiando i dischi rigidi ottengo una velocità maggiore specificando bs=1Mche utilizzando bs=4ko l'impostazione predefinita. Sto parlando di miglioramenti della velocità dal 30 al 300 percento. Non è necessario sintonizzarlo per il meglio in assoluto, a meno che non sia tutto ciò che fai ogni giorno. ma scegliere qualcosa di meglio del valore predefinito può ridurre le ore del tempo di esecuzione.

Quando lo si utilizza per davvero provare alcuni numeri diversi e inviare al ddprocesso un SIGUSR1segnale per farlo emettere un rapporto di stato in modo da poter vedere come sta andando.

✗ 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

2014 Macbook Pro Retina copia su chiavetta USB3 valutato a 90 MB / s in scrittura: $ sudo dd if=~/Downloads/Qubes-R4.0-rc4-x86_64.iso of=/dev/rdisk2 status=progressmostra 6140928 bytes (6.1 MB, 5.9 MiB) copied, 23 s, 267 kB/s. L'ho annullato perché stava impiegando troppo tempo. Ora specificando il bytesize: $ sudo dd if=~/Downloads/Qubes-R4.0-rc4-x86_64.iso of=/dev/rdisk2 bs=1M status=progressspettacoli4558159872 bytes (4.6 GB, 4.2 GiB) copied, 54 s, 84.4 MB/s
Eric Duncan

9

Per quanto riguarda il disco rigido interno, almeno - quando stai leggendo dal dispositivo , almeno il livello di blocco deve recuperare un settore che è di 512 byte.

Quindi, quando gestisci una lettura di 1 byte hai letto davvero solo dal disco sul recupero byte allineato al settore. Le restanti 511 volte sono gestite dalla cache.

Puoi dimostrarlo come segue, in questo esempio sdbè un disco di interesse:

# 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 quarta colonna (che conta le letture) indica che si è verificata solo 1 lettura, nonostante il fatto che tu abbia richiesto letture di 1 byte. Si tratta di un comportamento previsto poiché questo dispositivo (un disco SATA 2) deve restituire al minimo le dimensioni del settore. Il kernel sta semplicemente memorizzando nella cache l'intero settore.

Il principale fattore in gioco in queste richieste di dimensioni è l'overhead dell'emissione di una chiamata di sistema per una lettura o una scrittura. In effetti, l'emissione della chiamata per <512 è inefficiente. Letture molto grandi richiedono meno chiamate di sistema al costo di più memoria utilizzata per farlo.

4096 è in genere un numero "sicuro" per la lettura perché:

  • Quando si legge con la memorizzazione nella cache attivata (impostazione predefinita), una pagina è 4K. Riempire una pagina con <4k letture è più complicato che mantenere le dimensioni di lettura e pagina uguali.
  • La maggior parte delle dimensioni dei blocchi del filesystem sono impostate su 4k.
  • Non è un numero abbastanza piccolo (forse per gli SSD è ora) per causare overhead di syscall ma non un numero abbastanza grande da consumare molta memoria.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.