64k scheint eine gute Wahl zu sein:
Results:
no bs= 78s 144584+0 records
bs=512 78s 144584+0 records
bs=1k 38s 72292+0 records
bs=2k 38s 36146+0 records
bs=4k 38s 18073+0 records
bs=5k 39s 14458+1 records
bs=50k 38s 1445+1 records
bs=500k 39s 144+1 records
bs=512k 39s 144+1 records
bs=1M 39s 72+1 records
bs=5M 39s 14+1 records
bs=10M 39s 7+1 records
(entnommen von hier).
dies stimmt mit meinen eigenen Erkenntnissen über das Puffern von Lese-/Schreibvorgängen überein, um ein io-lastiges Konverterprogramm zu beschleunigen, das ich einmal an @work gepimpt habe.
dd kopiert gerne mit dem BS alles, was Sie wollen, und kopiert einen Teilblock (am Ende).
Grundsätzlich scheint der Blockgrößenparameter (bs) die Menge an Speicher festzulegen, die verwendet wird, um einen Klumpen von einer Festplatte einzulesen, bevor versucht wird, diesen Klumpen auf die andere zu schreiben.
Wenn Sie über viel RAM verfügen, bedeutet das Vergrößern des BS (aber vollständig im RAM enthalten), dass das E / A-Subsystem so weit wie möglich ausgelastet wird, indem massiv große Lese- und Schreibvorgänge durchgeführt werden - unter Ausnutzung des RAM. Wenn Sie den BS klein machen, bedeutet dies, dass der I/O-Overhead im Verhältnis zur Gesamtaktivität steigt.
Natürlich gibt es dabei ein Gesetz des abnehmenden Ertrags. Meine grobe Annäherung ist, dass eine Blockgröße im Bereich von etwa 128 KB bis 32 MB wahrscheinlich eine solche Leistung erbringen wird, dass der Overhead im Vergleich zur einfachen E / A gering ist und eine Vergrößerung keinen großen Unterschied macht. Der Grund dafür, dass die Untergrenze 128 KB bis 32 MB beträgt, ist, dass dies von Ihrem Betriebssystem, Ihrer Hardware usw. abhängt.
Wenn ich es wäre, würde ich ein paar Experimente durchführen, um eine Kopie/einen Klon mit einem BS von 128K und erneut mit (sagen wir) 16M zu timen. Wenn man merklich schneller ist, benutze es. Wenn nicht, dann verwenden Sie den kleineren BS der beiden.
Wie andere gesagt haben, gibt es keine allgemein korrekte Blockgröße; Was für eine Situation optimal ist, oder ein Hardwareteil kann für eine andere schrecklich ineffizient sein. Abhängig vom Zustand der Festplatten kann es auch vorzuziehen sein, eine andere Blockgröße als die "optimale" zu verwenden.
Eine Sache, die auf moderner Hardware ziemlich zuverlässig ist, ist, dass die Standard-Blockgröße von 512 Bytes dazu neigt, fast eine Größenordnung langsamer zu sein als eine optimalere Alternative. Im Zweifelsfall habe ich festgestellt, dass 64K ein ziemlich solider moderner Standard ist. Obwohl 64K normalerweise nicht DIE optimale Blockgröße ist, ist sie meiner Erfahrung nach viel effizienter als der Standardwert. 64K hat auch eine ziemlich solide Geschichte der zuverlässigen Leistung:Sie finden hier eine Nachricht von der Eug-Lug-Mailingliste, circa 2002, die eine Blockgröße von 64K empfiehlt:http://www.mail-archive.com/example@ unixlinux.online/msg12073.html
Um DIE optimale Ausgabeblockgröße zu bestimmen, habe ich das folgende Skript geschrieben, das das Schreiben einer 128 MB großen Testdatei mit dd bei einer Reihe unterschiedlicher Blockgrößen testet, von der Standardeinstellung von 512 Byte bis zu einem Maximum von 64 MB. Seien Sie gewarnt, dieses Skript verwendet intern dd, verwenden Sie es also mit Vorsicht.
dd_obs_test.sh:
#!/bin/bash
# Since we're dealing with dd, abort if any errors occur
set -e
TEST_FILE=${1:-dd_obs_testfile}
TEST_FILE_EXISTS=0
if [ -e "$TEST_FILE" ]; then TEST_FILE_EXISTS=1; fi
TEST_FILE_SIZE=134217728
if [ $EUID -ne 0 ]; then
echo "NOTE: Kernel cache will not be cleared between tests without sudo. This will likely cause inaccurate results." 1>&2
fi
# Header
PRINTF_FORMAT="%8s : %s\n"
printf "$PRINTF_FORMAT" 'block size' 'transfer rate'
# Block sizes of 512b 1K 2K 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M
for BLOCK_SIZE in 512 1024 2048 4096 8192 16384 32768 65536 131072 262144 524288 1048576 2097152 4194304 8388608 16777216 33554432 67108864
do
# Calculate number of segments required to copy
COUNT=$(($TEST_FILE_SIZE / $BLOCK_SIZE))
if [ $COUNT -le 0 ]; then
echo "Block size of $BLOCK_SIZE estimated to require $COUNT blocks, aborting further tests."
break
fi
# Clear kernel cache to ensure more accurate test
[ $EUID -eq 0 ] && [ -e /proc/sys/vm/drop_caches ] && echo 3 > /proc/sys/vm/drop_caches
# Create a test file with the specified block size
DD_RESULT=$(dd if=/dev/zero of=$TEST_FILE bs=$BLOCK_SIZE count=$COUNT conv=fsync 2>&1 1>/dev/null)
# Extract the transfer rate from dd's STDERR output
TRANSFER_RATE=$(echo $DD_RESULT | \grep --only-matching -E '[0-9.]+ ([MGk]?B|bytes)/s(ec)?')
# Clean up the test file if we created one
if [ $TEST_FILE_EXISTS -ne 0 ]; then rm $TEST_FILE; fi
# Output the result
printf "$PRINTF_FORMAT" "$BLOCK_SIZE" "$TRANSFER_RATE"
done
Auf GitHub ansehen
Ich habe dieses Skript nur auf einem Debian (Ubuntu)-System und auf OSX Yosemite getestet, daher wird es wahrscheinlich einige Anpassungen erfordern, damit es auf anderen Unix-Varianten funktioniert.
Standardmäßig erstellt der Befehl eine Testdatei namens dd_obs_testfile im aktuellen Verzeichnis. Alternativ können Sie einen Pfad zu einer benutzerdefinierten Testdatei angeben, indem Sie nach dem Skriptnamen einen Pfad angeben:
$ ./dd_obs_test.sh /path/to/disk/test_file
Die Ausgabe des Skripts ist eine Liste der getesteten Blockgrößen und ihrer jeweiligen Übertragungsraten wie folgt:
$ ./dd_obs_test.sh
block size : transfer rate
512 : 11.3 MB/s
1024 : 22.1 MB/s
2048 : 42.3 MB/s
4096 : 75.2 MB/s
8192 : 90.7 MB/s
16384 : 101 MB/s
32768 : 104 MB/s
65536 : 108 MB/s
131072 : 113 MB/s
262144 : 112 MB/s
524288 : 133 MB/s
1048576 : 125 MB/s
2097152 : 113 MB/s
4194304 : 106 MB/s
8388608 : 107 MB/s
16777216 : 110 MB/s
33554432 : 119 MB/s
67108864 : 134 MB/s
(Hinweis:Die Einheit der Übertragungsraten variiert je nach Betriebssystem)
Um die optimale Leseblockgröße zu testen, könnten Sie mehr oder weniger denselben Prozess verwenden, aber anstatt von /dev/zero zu lesen und auf die Festplatte zu schreiben, würden Sie von der Festplatte lesen und nach /dev/null schreiben. Ein Skript dafür könnte so aussehen:
dd_ibs_test.sh:
#!/bin/bash
# Since we're dealing with dd, abort if any errors occur
set -e
TEST_FILE=${1:-dd_ibs_testfile}
if [ -e "$TEST_FILE" ]; then TEST_FILE_EXISTS=$?; fi
TEST_FILE_SIZE=134217728
# Exit if file exists
if [ -e $TEST_FILE ]; then
echo "Test file $TEST_FILE exists, aborting."
exit 1
fi
TEST_FILE_EXISTS=1
if [ $EUID -ne 0 ]; then
echo "NOTE: Kernel cache will not be cleared between tests without sudo. This will likely cause inaccurate results." 1>&2
fi
# Create test file
echo 'Generating test file...'
BLOCK_SIZE=65536
COUNT=$(($TEST_FILE_SIZE / $BLOCK_SIZE))
dd if=/dev/urandom of=$TEST_FILE bs=$BLOCK_SIZE count=$COUNT conv=fsync > /dev/null 2>&1
# Header
PRINTF_FORMAT="%8s : %s\n"
printf "$PRINTF_FORMAT" 'block size' 'transfer rate'
# Block sizes of 512b 1K 2K 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M
for BLOCK_SIZE in 512 1024 2048 4096 8192 16384 32768 65536 131072 262144 524288 1048576 2097152 4194304 8388608 16777216 33554432 67108864
do
# Clear kernel cache to ensure more accurate test
[ $EUID -eq 0 ] && [ -e /proc/sys/vm/drop_caches ] && echo 3 > /proc/sys/vm/drop_caches
# Read test file out to /dev/null with specified block size
DD_RESULT=$(dd if=$TEST_FILE of=/dev/null bs=$BLOCK_SIZE 2>&1 1>/dev/null)
# Extract transfer rate
TRANSFER_RATE=$(echo $DD_RESULT | \grep --only-matching -E '[0-9.]+ ([MGk]?B|bytes)/s(ec)?')
printf "$PRINTF_FORMAT" "$BLOCK_SIZE" "$TRANSFER_RATE"
done
# Clean up the test file if we created one
if [ $TEST_FILE_EXISTS -ne 0 ]; then rm $TEST_FILE; fi
Auf GitHub ansehen
Ein wichtiger Unterschied besteht in diesem Fall darin, dass die Testdatei eine Datei ist, die vom Skript geschrieben wird. Richten Sie diesen Befehl nicht auf eine existierende Datei oder die existierende Datei wird mit zufälligen Daten überschrieben!
Für meine spezielle Hardware fand ich heraus, dass 128 KB die optimalste Eingangsblockgröße auf einer Festplatte und 32 KB die optimalste auf einer SSD war.
Obwohl diese Antwort die meisten meiner Erkenntnisse abdeckt, bin ich oft genug auf diese Situation gestoßen, dass ich einen Blog-Beitrag darüber geschrieben habe:http://blog.tdg5.com/tuning-dd-block-size/ Sie können weitere Einzelheiten finden auf die Tests, die ich dort durchgeführt habe.
Dieser StackOverflow-Beitrag kann auch hilfreich sein:dd:Wie berechnet man die optimale Blockgröße?