Gibt es eine Möglichkeit, den optimalen Wert für den Parameter bs für dd zu ermitteln?

71

Gelegentlich habe ich Kommentare online gesehen, die lauten: "Stellen Sie sicher, dass Sie 'bs =' setzen, da der Standardwert zu lange dauert." Zeit letzte Woche "scheinen das zu belegen. Wenn ich 'dd' verwende (normalerweise im Bereich von 1-2 GB), muss der Parameter bytes angegeben werden. Ungefähr die Hälfte der Zeit verwende ich den Wert, der in dem Online-Handbuch angegeben ist, aus dem ich kopiere. den Rest der Zeit wähle ich eine Nummer aus der 'fdisk -l'-Liste, von der ich annehme, dass sie langsamer ist (z. B. die SD-Karte, auf die ich schreibe).

Gibt es für eine bestimmte Situation (Medientyp, Busgröße oder was auch immer wichtig ist) eine Möglichkeit, einen "besten" Wert zu ermitteln? Ist es leicht zu bestimmen? Wenn nicht, gibt es einen einfachen Weg, um 90-95% des Weges dorthin zu bekommen? Oder ist "nur etwas größer als 512 auswählen" sogar die richtige Antwort?

Ich habe darüber nachgedacht, das Experiment selbst auszuprobieren, bin mir aber nicht sicher, welche Faktoren die Antwort beeinflussen, und weiß daher nicht, wie ich ein gutes Experiment entwerfen soll.

Drewbenn
quelle
Das Schreiben auf dasselbe Speichermedium unterscheidet sich vom Schreiben auf ein anderes Speichermedium und erfordert unterschiedliche optimale Einstellungen. Es gibt viele Variablen, die je nach Gerätetyp, Geschwindigkeit, Cache usw. für jeden unterschiedlich sind. Auf meiner Maschine ist bs = 256M optimal.

Antworten:

27

ddstammt aus der Zeit, als es für die Übersetzung alter IBM-Mainframe-Bänder erforderlich war, und die Blockgröße musste mit der übereinstimmen, die zum Schreiben des Bandes verwendet wurde, oder Datenblöcke wurden übersprungen oder abgeschnitten. (9-Spur-Bänder waren heikel. Seien Sie froh, dass sie lange tot sind.) Heutzutage sollte die Blockgröße ein Vielfaches der Größe des Gerätesektors sein (normalerweise 4 KB), aber auf neueren Festplatten können sie viel größer sein und einen sehr kleinen Daumen haben Laufwerke mögen kleiner sein, aber 4 KB sind ein vernünftiger Mittelweg, und je größer, desto besser für die Leistung. Ich verwende oft 1MB Blockgrößen mit Festplatten. (Wir haben heutzutage auch viel mehr Gedächtnis.)

Geekosaurier
quelle
Festplatten oder USB-Massenspeichergeräte haben 512 oder 4096 (neuere) Bytes. Flash-Medien mit optischem und direktem Zugriff haben eine Größe von 2048 Byte. Mit 4096 Bytes kann man nichts falsch machen.
LawrenceC
3
Warum sollte die Blockgröße des Kopierprogramms etwas mit den Eigenschaften des zugrunde liegenden Geräts zu tun haben (ausgenommen Bänder)? Der Kernel führt sowieso seine eigene Pufferung (und manchmal Vorablesezugriff) durch.
Gilles
1
Bruchpuffer zu minimieren; Wenn Sie ausgerichtete Puffer verwenden, werden die Dinge im Allgemeinen schneller, da der Kernel Puffer-Lese- / Schreibvorgänge im Sektor (oder besser, Spur oder Zylinder, aber ich denke, moderne Laufwerke lügen über diese) und Kernel-Puffergrenzen starten kann, weil der Kernel keine hat Überspringen oder Lesen von zusätzlichen Inhalten oder Verwalten von Teilpuffern. Natürlich können Sie den Kernel einfach alles erledigen lassen, aber wenn Sie Gigabyte an Daten kopieren, kann diese zusätzliche Arbeit die Kopierzeit erheblich verkürzen.
Geekosaurier
Sie müssen (im Allgemeinen) angeben, @Gillesob ich über Ihre Kommentarantwort benachrichtigt werden soll. Weitere Informationen finden Sie unter Wie funktioniert die Funktion von comment @replies ?. . Da ich zufällig vorbeikam: Der Kernel wird sich sowieso darum kümmern. Ihre Behauptung, dass "diese zusätzliche Arbeit die Kopierzeit erheblich verkürzen kann", stimmt nicht mit meinen Benchmarks überein, aber verschiedene Systeme können sich unterschiedlich verhalten, also tragen Sie bitte auch das Timing bei!
Gilles
@ Gilles: Entschuldigung, ich hatte dich für den ursprünglichen Fragesteller gehalten.
Geekosaurier
60

Es gibt nur einen Weg, die optimale Blockgröße zu bestimmen, und das ist ein Maßstab. Ich habe gerade einen kurzen Benchmark gemacht. Die Testmaschine ist ein PC, auf dem Debian GNU / Linux mit Kernel 2.6.32 und Coreutils 8.5 ausgeführt wird. Beide beteiligten Dateisysteme sind ext3 auf LVM-Volumes auf einer Festplattenpartition. Die Quelldatei hat eine Größe von 2 GB (2040000 KB, um genau zu sein). Caching und Pufferung sind aktiviert. Vor jedem Lauf habe ich den Cache mit geleert sync; echo 1 >|/proc/sys/vm/drop_caches. Die Laufzeiten enthalten kein Finale synczum Leeren der Puffer. Das Finale syncdauert in der Größenordnung von 1 Sekunde. Die sameLäufe waren Kopien auf demselben Dateisystem; Die diffLäufe waren Kopien in ein Dateisystem auf einer anderen Festplatte. Aus Gründen der Konsistenz sind die angegebenen Zeiten die mit der. Erhaltenen WanduhrzeitentimeNutzen, in Sekunden. Ich habe jeden Befehl nur einmal ausgeführt, daher weiß ich nicht, wie stark das Timing variiert.

             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

Fazit: Eine große Blockgröße (mehrere Megabyte) hilft, aber nicht dramatisch (viel weniger, als ich für Kopien mit demselben Laufwerk erwartet hatte). Und catund cpnicht so schlecht abschneiden. Mit diesen Zahlen finde ich es nicht ddwert , mich damit zu beschäftigen. Geh mit cat!

Gilles
quelle
Ich würde dem OP empfehlen, sein eigenes Benchmarking durchzuführen, aber trotzdem, nette Antwort!
Ninjalj
5
@Nikhil >|ist dasselbe wie, >außer dass unter set -o noclobberdie Shell beschwert, dass die Datei existiert, wenn Sie verwenden >.
Gilles
2
@Masi Ja, wenn ich eine ganze Platte klonen will, benutze ich cat. Warum suchst du einen besseren Weg? Was ist los mit cat?
Gilles
5
@Masi catkopiert nur seine Eingabe in seine Ausgabe. Wenn Sie von unzuverlässigen Medien kopieren und nicht lesbare Teile überspringen oder mehrmals wiederholen möchten, ist dies ein anderes Problem, für das es sehr gut ddrescuefunktioniert.
Gilles
1
@sudo Sie können die Menge der kopierten Daten abrufen lsof. Die augenblickliche Geschwindigkeit ist bei einer Festplattenkopie nicht sehr relevant, da sie einheitlich ist, sodass Sie die übertragenen Bytes durch die verstrichene Zeit teilen können. Wenn Sie etwas besseres wollen, können Sie verwenden pv.
Gilles
8

Ich stimme dem Geekosaurier zu, dass die Größe ein Vielfaches der Blockgröße sein sollte, die oft 4 KB beträgt.

Wenn Sie die Blockgröße finden möchten, stat -c "%o" filenameist dies wahrscheinlich die einfachste Option.

Aber sagen Sie dd bs=4K, das heißt, es tut read(4096); write(4096); read(4096); write(4096)...

Jeder Systemaufruf ist mit einem Kontextwechsel verbunden, der mit einem gewissen Aufwand verbunden ist. Je nach E / A-Planer können Lesevorgänge mit dazwischenliegenden Schreibvorgängen dazu führen, dass die Festplatte viele Suchvorgänge ausführt. (Wahrscheinlich kein großes Problem mit dem Linux-Scheduler, aber dennoch ein Grund zum Nachdenken.)

Wenn Sie dies tun bs=8K, lassen Sie die Festplatte zwei Blöcke gleichzeitig lesen, die sich wahrscheinlich nahe beieinander auf der Festplatte befinden, bevor Sie den Schreibvorgang an einer anderen Stelle ausführen (oder die E / A für einen anderen Prozess warten).

Nach dieser Logik bs=16Kist noch besser, etc.

Ich würde also gerne wissen, ob es eine Obergrenze gibt, an der die Leistung schlechter wird, oder ob sie nur durch das Gedächtnis begrenzt ist.

Mikel
quelle
4
Profil, spekuliere nicht!
Gilles
1
Die Linux-Programmierschnittstelle stimmt mit mir überein. Siehe Kapitel 13 - Datei-E / A-Pufferung.
Mikel
4
Interessanterweise deuten ihre Benchmarks jedoch darauf hin, dass es oberhalb von 4K nur einen geringen Nutzen gibt.
Mikel
4
Außerdem ist das Standardfenster für das Vorauslesen von Dateien offenbar 128 KB groß, sodass dieser Wert möglicherweise von Vorteil ist.
Mikel
6
Ich habe hier Zugriff auf ein RAID50 mit 24 Laufwerken, wobei bs = 8K mir 197 MB / s bringt, aber bs = 1M mir 2,2 GB / s bringt, was dem theoretischen Durchsatz des RAID nahe kommt. Also bs ist VIEL wichtig. Mit bs = 10M bekomme ich jedoch nur 1,7 GB / s. Es scheint also ab einer gewissen Schwelle schlimmer zu werden, aber ich weiß nicht warum.
Joseph Garvin
5

Wie Gilles sagt, können Sie den optimalen Parameter für die Option bs to dd durch Benchmarking bestimmen. Dies wirft jedoch die Frage auf: Wie können Sie diesen Parameter bequem bewerten?

Meine vorläufige Antwort auf diese Frage lautet: benutze dd-opt , das Dienstprogramm, an dem ich kürzlich gearbeitet habe, um genau dieses Problem zu lösen :)

sampablokuper
quelle
1
Was ist die Empfindlichkeit der Ausgabe? 90-95% oder> 95%? Ich finde nicht, dass du es ändern kannst.
Léo Léopold Hertz 준영
1
@Masi, ich fürchte, ich habe lange nicht mehr daran gearbeitet dd-opt. Es handelt sich jedoch um freie Software, die unter der AGPLv3 lizenziert ist . Fühlen Sie sich also frei, es zu verbessern und seine Empfindlichkeit / Genauigkeit zu bewerten!
sampablokuper
0

Ich optimiert für SD-Kartenleser USB2.0, die am besten zu laufen scheint bs=10M. Ich habe versucht 4k, auf bis zu 16M, nach 8-10M keine Besserung. Sie können sehen, wie sich die Übertragungsrate verschlechtert. Dies liegt wahrscheinlich daran, dass die Puffer auf dem Gerät geladen werden und darauf gewartet wird, dass das Gerät auf das eigentliche Medium übertragen wird.

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
quelle