C'è un modo per determinare il valore ottimale per il parametro bs su dd?


71

A volte ho visto commenti online sulla falsariga di "assicurati di impostare 'bs =' perché il valore predefinito richiederà troppo tempo" e le mie esperienze estremamente non scientifiche di "beh, che sembra richiedere più tempo di quello tempo della scorsa settimana "sembra confermarlo. Quindi ogni volta che utilizzo 'dd' (in genere nell'intervallo 1-2 GB) mi assicuro di specificare il parametro bytes. Circa la metà delle volte utilizzo il valore specificato in qualsiasi guida online da cui sto copiando; il resto del tempo sceglierò un numero che ha senso dall'elenco 'fdisk -l' per quello che presumo sia il supporto più lento (ad esempio la scheda SD su cui sto scrivendo).

Per una determinata situazione (tipo di supporto, dimensioni del bus o qualsiasi altra cosa importante), c'è un modo per determinare un valore "migliore"? È facile da determinare? In caso contrario, c'è un modo semplice per ottenere il 90-95% del percorso lì? Oppure "scegli qualcosa di più grande di 512" è la risposta corretta?

Ho pensato di provare l'esperimento da solo, ma (oltre a essere un sacco di lavoro) non sono sicuro di quali fattori influenzino la risposta, quindi non so come progettare un buon esperimento.


scrivere sullo stesso supporto di archiviazione è diverso rispetto alla scrittura su un supporto di archiviazione diverso e richiederebbe impostazioni ottimali diverse, ci sono molte variabili che saranno diverse per tutti, a seconda del tipo di dispositivo, della velocità, della cache e così via. Sulla mia macchina bs = 256M è ottimale.

Risposte:


27

ddrisale a quando era necessario tradurre vecchi nastri mainframe IBM e la dimensione del blocco doveva corrispondere a quella utilizzata per scrivere il nastro o i blocchi di dati sarebbero stati saltati o troncati. (I nastri a 9 tracce erano pignoli. Sii contento che siano morti da tempo.) Al giorno d'oggi, la dimensione del blocco dovrebbe essere un multiplo della dimensione del settore del dispositivo (di solito 4KB, ma su dischi molto recenti potrebbe essere molto più grande e su pollice molto piccolo le unità possono essere più piccole, ma 4KB è una via di mezzo ragionevole a prescindere) e maggiore è il migliore per le prestazioni. Uso spesso blocchi da 1 MB con dischi rigidi. (Abbiamo molta più memoria da gettare anche in questi giorni.)


I dischi rigidi o i dispositivi di archiviazione di massa USB sono 512 o 4096 (più recenti) byte. Il supporto flash con accesso ottico e diretto è di 2048 byte. Impossibile sbagliare con 4096 byte.
LawrenceC

3
Perché la dimensione del blocco del programma di copia dovrebbe avere qualcosa a che fare con le caratteristiche del dispositivo sottostante (esclusi i nastri)? Il kernel esegue comunque il proprio buffering (e talvolta il prefetching).
Gilles 'SO-smetti di essere malvagio' il

1
Ridurre al minimo i buffer frazionari; le cose in generale vanno più veloci quando usi i buffer allineati perché il kernel può avviare le letture / scritture del buffer nel settore (o meglio, traccia o cilindro, ma penso che le unità moderne mentano su quelle) e i limiti del buffer del kernel, perché il kernel non ha per saltare cose o leggere cose extra o gestire buffer parziali. Certamente puoi semplicemente lasciare che il kernel gestisca tutto, ma se stai copiando gigabyte di dati quel lavoro extra può ridurre notevolmente i tempi di copia.
geekosaur,

In genere, è necessario includere @Gillesse si desidera che riceva una notifica della risposta del commento, vedere Come funzionano i commenti @ risposta ? . Da quando mi è capitato di passare: il kernel si occuperà comunque di tutto. La tua affermazione che "quel lavoro extra può ridurre notevolmente i tempi di copia" non è d'accordo con i miei parametri di riferimento, ma sistemi diversi possono avere comportamenti diversi, quindi per favore contribuisci anche con i tempi!
Gilles 'SO- smetti di essere malvagio' il

@Gilles: scusa, ti avevo scambiato per il richiedente originale.
geekosaur,

60

C'è solo un modo per determinare la dimensione ottimale del blocco, e questo è un punto di riferimento. Ho appena fatto un rapido benchmark. La macchina di prova è un PC con Debian GNU / Linux, con kernel 2.6.32 e coreutils 8.5. Entrambi i filesystem coinvolti sono ext3 su volumi LVM su una partizione del disco rigido. Il file sorgente è 2 GB (2040000kB per la precisione). La memorizzazione nella cache e il buffering sono abilitati. Prima di ogni esecuzione, ho svuotato la cache con sync; echo 1 >|/proc/sys/vm/drop_caches. I tempi di esecuzione non includono un finale syncper svuotare i buffer; la finale syncprende l'ordine di 1 secondo. Le sameesecuzioni erano copie sullo stesso filesystem; le diffesecuzioni erano copie su un filesystem su un altro disco rigido. Per coerenza, i tempi riportati sono i tempi dell'orologio da parete ottenuti con iltimeutilità, in pochi secondi. Ho eseguito ogni comando una sola volta, quindi non so quanta varianza ci sia nei tempi.

             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

Conclusione: una grande dimensione del blocco (diversi megabyte) aiuta, ma non in modo drammatico (molto meno di quanto mi aspettassi per le copie della stessa unità). E cate cpnon esibirti così male. Con questi numeri, non trovo dddegno di preoccuparsi. Vai con cat!


Consiglierei all'OP di fare il suo benchmarking, ma comunque, bella risposta!
ninjalj,

5
@Nikhil >|è lo stesso di >quello sotto set -o noclobber, la shell si lamenterà che il file esiste se lo usi >.
Gilles 'SO- smetti di essere malvagio' il

2
@Masi Sì, se voglio clonare un intero disco, lo userò cat. Perché stai cercando un modo migliore? Cosa c'è che non va cat?
Gilles 'SO- smetti di essere malvagio'

5
@Masi catcopia semplicemente il suo input nel suo output. Se si desidera copiare da supporti inaffidabili e saltare parti illeggibili o riprovare più volte, si tratta di un problema diverso, per il quale ddrescuefunziona abbastanza bene.
Gilles 'SO- smetti di essere malvagio'

1
@sudo È possibile ottenere la quantità di dati copiati lsof. La velocità istantanea non è molto rilevante con una copia del disco perché è uniforme in modo da poter dividere i byte trasferiti per il tempo trascorso; se vuoi qualcosa di meglio, puoi usare pv.
Gilles 'SO- smetti di essere malvagio'

8

Concordo con il geekosaur che la dimensione dovrebbe essere un multiplo della dimensione del blocco, che spesso è 4K.

Se vuoi trovare la dimensione del blocco stat -c "%o" filenameè probabilmente l'opzione più semplice.

Ma dimmi di dd bs=4Ksì, significa che lo fa read(4096); write(4096); read(4096); write(4096)...

Ogni chiamata di sistema comporta un cambio di contesto, che comporta un certo sovraccarico e, a seconda dello scheduler I / O, le letture con scritture intervallate potrebbero causare molte ricerche sul disco. (Probabilmente non è un grosso problema con lo scheduler di Linux, ma comunque qualcosa a cui pensare.)

Quindi, se lo fai bs=8K, permetti al disco di leggere due blocchi alla volta, che sono probabilmente vicini tra loro sul disco, prima di cercare altrove di scrivere (o di servire l'I / O per un altro processo).

Secondo quella logica, bs=16Kè ancora meglio, ecc.

Quindi quello che mi piacerebbe sapere è se esiste un limite superiore in cui le prestazioni iniziano a peggiorare o se è limitato solo dalla memoria.


4
Profilo, non speculare!
Gilles 'SO-smetti di essere malvagio' il

1
L'interfaccia di programmazione Linux è d' accordo con me. Vedere il capitolo 13 - Buffer I / O dei file.
Mikel,

4
È interessante notare che i loro benchmark suggeriscono che ci sono pochi benefici sopra 4K.
Mikel,

4
Inoltre, apparentemente la finestra di lettura anticipata del file predefinito è 128 KB, quindi questo valore potrebbe essere utile.
Mikel,

6
Ho accesso a un RAID50 a 24 unità qui, dove bs = 8K mi dà 197 MB / s ma bs = 1M mi dà 2,2 GB / s che è vicino al throughput teorico del RAID. Quindi bs conta MOLTO. Comunque usando bs = 10M ottengo solo 1,7 GB / s. Quindi sembra peggiorare oltre qualche soglia, ma non so perché.
Joseph Garvin,

5

Come dice Gilles, puoi determinare il parametro ottimale per l' opzione bs da dd mediante benchmarking. Questo, tuttavia, pone la domanda: come si può comodamente confrontare questo parametro?

La mia risposta provvisoria a questa domanda è: usa dd-opt , l'utilità su cui ho recentemente iniziato a lavorare per risolvere esattamente questo problema :)


1
Qual è la sensibilità dell'uscita? 90-95% o> 95%? Non trovo che tu possa cambiarlo.
Léo Léopold Hertz

1
@Masi, temo di non aver lavorato per dd-optmolto tempo. Tuttavia, è un software gratuito concesso in licenza in base all'AGPLv3 . Quindi, sentiti libero di migliorarlo e di valutarne la sensibilità / accuratezza!
sampablokuper,

0

Ho ottimizzato per il lettore sdcard usb2.0 che sembra funzionare al meglio bs=10M. Ho provato 4k, fino a 16M, dopo 8-10M nessun miglioramento. Puoi vedere come la misurazione della velocità di trasferimento si degrada ... molto probabilmente a causa del caricamento dei buffer sul dispositivo, quindi in attesa del trasferimento del dispositivo sul supporto effettivo.

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
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.