Frage Verbessert die Option "bs" in "dd" wirklich die Geschwindigkeit?


Hin und wieder wurde mir gesagt, dass ich zur Erhöhung der Geschwindigkeit eines "dd" sorgfältig eine richtige "Blockgröße" wählen sollte.

Auch hier, auf ServerFault, jemand anderes schrieb Das "... die optimale Blockgröße ist hardwareabhängig ..." (Iaine) oder "... die perfekte Größe hängt von Ihrem Systembus, dem Festplattencontroller, dem jeweiligen Laufwerk und den Treibern ab ..." (chris-s)

Da mein Gefühl ein bisschen anders war (BTW: Ich habe mir gedacht, dass die Zeit, die benötigt wird, um den bs-Parameter tief abzustimmen, viel höher war als der erhaltene Gewinn, was Zeiteinsparungen angeht, und dass der Standard vernünftig war), heute habe ich einfach ein paar schnelle Benchmarks durchgespielt.

Um äußere Einflüsse zu verringern, beschloss ich zu lesen:

  • von einer externen MMC-Karte
  • von einer internen Partition

und:

  • mit verwandten Dateisystemen ummounted
  • Senden der Ausgabe an / dev / null, um Probleme im Zusammenhang mit "Schreibgeschwindigkeit" zu vermeiden;
  • einige grundlegende Probleme des HDD-Caching zu vermeiden, zumindest wenn es um die Festplatte geht.

In der folgenden Tabelle habe ich meine Ergebnisse gemeldet und 1 GB Daten mit verschiedenen Werten von "bs" gelesen (Sie können die rohen Zahlen am Ende dieser Nachricht finden):

enter image description here

Grundsätzlich kommt es heraus, dass:

  • MMC: mit einem bs = 4 (ja! 4 Bytes) habe ich einen Durchsatz von 12MB / s erreicht. Ein nicht so weit entfernter Wert von 14.2 / 14.3, den ich von bs = 5 und höher bekommen habe;

  • HDD: mit einem bs = 10 habe ich 30 MB / s erreicht. Sicherlich niedriger als die 95,3 MB mit der Standard-BS = 512, aber ... auch signifikant.

Es war auch sehr klar, dass die CPU-Systemzeit umgekehrt proportional zum BS-Wert war (aber das klingt vernünftig, je niedriger die BS ist, desto höher ist die Anzahl der von dd erzeugten SYS-Aufrufe).

Nachdem ich all das gesagt habe, stellt sich nun die Frage: Kann jemand erklären (ein Kernel-Hacker?), Was sind die Hauptkomponenten / Systeme, die an einem solchen Durchsatz beteiligt sind, und wenn es sich wirklich lohnt, einen höheren BS als den Standard anzugeben?


MMC-Fall - rohe Zahlen

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-Fall - rohe Zahlen

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 (Versetzen des Lesevorgangs, um Zwischenspeichern zu vermeiden)

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 des Lesevorgangs, um Zwischenspeichern zu vermeiden)

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 des Lesevorgangs, um Zwischenspeichern zu vermeiden)

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

51
2017-12-08 20:34


Ursprung


Was wäre wirklich schön, ein zu haben bs=auto Feature in dd Dadurch wird der optimale BS-Parameter vom Gerät erkannt und verwendet.
Was wäre wenn äußerst nett ist eine Grafik von mehreren bs Größen aufgetragen gegen die Geschwindigkeit statt 15 Dutzend Codeblöcke in einer einzigen Frage. Würde weniger Platz nehmen und sein unendlich schneller zu lesen. Ein Bild wirklich ist wert eine thoursand worte. - MDMoore313
@ BigHomie - Ich habe über das Bereitstellen eines Graphen gelernt, aber ... es gibt mehrere "Skalierungsprobleme". Es würde wahrscheinlich eine logarithmische Skala auf beiden Achsen und ... während ich daran dachte, dachte ich, es war kein einfaches (und schnelles) Problem zu lösen. Also wechselte ich zur "table" -Version. Was die "... 15 Dutzend Code-Blöcke" betrifft, so wollte ich, dass jeder die Möglichkeit hatte, "rohe Zahlen" zu überprüfen, um jegliche (persönliche) Störung zu vermeiden. - Damiano Verzulli
@DamianoVerzulli der Tisch ist cool, bitte ignorieren Sie meine Schimpfwörter, ich gab Ihnen eine Aufwertung, um unseren Aberglauben trotzdem zu beweisen, und ich weiß aus erster Hand, dass das Hantieren mit der Byte-Größe die Geschwindigkeit verändert, ich könnte es auch in eine Antwort bringen. - MDMoore313
@warren - 4G bekommen können Sie auch tun bs=8k count=512K oder bs=1M count=4K Ich erinnere mich nicht an Potenzen von 2 nach 65536 - user313114


Antworten:


Was Sie getan haben, ist nur ein Lesegeschwindigkeitstest. Wenn Sie tatsächlich Blöcke auf ein anderes Gerät kopieren, die Sie während des Lesens anhalten, während das andere Gerät die Daten akzeptiert, die Sie schreiben möchten, können Sie in diesem Fall Probleme mit der Rotationslatenz auf dem Lesegerät (wenn es sich um eine Festplatte handelt) feststellen Es ist oft wesentlich schneller, 1M-Stücke von der Festplatte zu lesen, da Sie auf diese Weise weniger häufig auf Rotationslatenz reagieren.

Ich weiß wann ich bin Kopieren Festplatten Ich bekomme eine schnellere Rate durch Angabe bs=1M als mit bs=4k oder der Standardwert. Ich spreche Geschwindigkeitsverbesserungen von 30 bis 300 Prozent. Es gibt keine Notwendigkeit, es für absolutes Bestes zu stimmen, es sei denn, es ist alles, was Sie jeden Tag tun. Wenn Sie jedoch etwas Besseres als die Standardeinstellung auswählen, können Sie die Ausführungszeit um Stunden reduzieren.

Wenn Sie es wirklich verwenden, versuchen Sie ein paar verschiedene Zahlen und senden Sie die dd a SIGUSR1 signalisieren, dass es einen Statusbericht ausgibt, damit Sie sehen können, wie es läuft.

✗ 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

22
2017-12-09 00:57



2014 Macbook Pro Retina Kopieren auf USB3 Stick mit 90 MB / s bewertet schreiben: $ sudo dd if=~/Downloads/Qubes-R4.0-rc4-x86_64.iso of=/dev/rdisk2 status=progress zeigt an 6140928 bytes (6.1 MB, 5.9 MiB) copied, 23 s, 267 kB/s. Ich habe das abgesagt, weil es zu lange gedauert hat. Jetzt die Bytesize angeben: $ sudo dd if=~/Downloads/Qubes-R4.0-rc4-x86_64.iso of=/dev/rdisk2 bs=1M status=progress zeigt an 4558159872 bytes (4.6 GB, 4.2 GiB) copied, 54 s, 84.4 MB/s - Eric Duncan


In Bezug auf die interne Festplatte, zumindest - wenn Sie aus dem Gerät die Blockebene lesen wenigstens muss einen Sektor abrufen, der 512 Bytes umfasst.

Wenn Sie also einen 1-Byte-Lesevorgang durchführen, haben Sie nur wirklich von der Festplatte beim Sektor-ausgerichteten Byte-Abruf gelesen. Die restlichen 511 Mal werden mit Cache versorgt.

Sie können dies in diesem Beispiel wie folgt beweisen sdb ist eine Scheibe von 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
...

Die vierte Spalte (die Lesevorgänge zählt) zeigt an, dass nur 1 Lesevorgang aufgetreten ist, obwohl Sie 1 Byte Lesevorgänge angefordert haben. Dies ist das erwartete Verhalten, da dieses Gerät (eine SATA 2-Festplatte) muss auf ein Minimum gibt seine Sektorgröße zurück. Der Kernel speichert einfach den gesamten Sektor.

Der größte Faktor bei diesen Größenanfragen ist der Aufwand für das Ausgeben eines Systemaufrufs für ein Lesen oder Schreiben. In der Tat ist die Ausgabe des Aufrufs für <512 ineffizient. Sehr große Lesevorgänge erfordern weniger Systemaufrufe auf Kosten von mehr Speicher, der dazu verwendet wird.

4096 ist normalerweise eine 'sichere' Nummer zum Lesen, weil:

  • Beim Lesen mit Zwischenspeichern (Standard) ist eine Seite 4k. Das Auffüllen einer Seite mit <4.000 Lesevorgängen ist komplizierter, als die Lese- und Seitengröße gleich zu halten.
  • Die meisten Dateisystemblockgrößen sind auf 4k eingestellt.
  • Es ist nicht klein genug (vielleicht für SSDs ist es jetzt aber), Syscall-Overhead zu verursachen, aber nicht groß genug, um viel Speicher zu verbrauchen.

7
2018-01-12 02:36