web-dev-qa-db-ja.com

「dd」の「bs」オプションは本当に速度を向上させますか?

「dd」の速度を上げるには、適切な「ブロックサイズ」を慎重に選択する必要があると時々言われます。

ここでも、ServerFaultの他の誰か 書き込み その「...最適なブロックサイズはハードウェアに依存します...(iain) または "...最適なサイズは、システムバス、ハードドライブコントローラー、特定のドライブ自体、およびそれぞれのドライバーによって異なります... " (chris-s)

私の気持ちは少し違っていたので(BTW:bsパラメータを深く調整するために必要な時間は、時間の節約という観点から、受け取ったゲインよりもはるかに高いこと、そしてデフォルトは妥当でした)、今日、私はいくつかの汚いベンチマークを通過しました。

外部からの影響を減らすために、私は以下を読むことにしました。

  • 外部からMMCカード
  • 内部パーティションから

そして:

  • アンマウントされた関連ファイルシステム
  • 「書き込み速度」に関連する問題を回避するために、出力を/ dev/nullに送信します。
  • 少なくともHDDが関係する場合、HDDキャッシュのいくつかの基本的な問題を回避します。

次の表では、調査結果を報告し、「bs」の値が異なる1GBのデータを読み取っています(このメッセージの最後に未加工の数値があります):

enter image description here

基本的には、次のことがわかります。

  • MMC:bs = 4(はい!4バイト)で、12MB /秒のスループットに達しました。 bs = 5以上から取得した最大14.2/14.3までのそれほど遠くない値。

  • HDD:bs = 10で30 MB /秒に達しました。確かにデフォルトのbs = 512で得られた95.3 MBよりも小さいですが、重要です。

また、CPU sys-timeがbs値に反比例することは非常に明らかでした(ただし、bsが低いほど、ddによって生成されるsys-callsの数が多いため、これは妥当なように聞こえます)。

上記のすべてを述べた後、今の質問:誰かがそのようなスループットに関与する主要なコンポーネント/システムは何か(カーネルハッカー?)を説明できますか?また、デフォルトよりも高いbsを指定する努力に本当に価値があるか?


MMCケース-未加工の数値

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ケース-生の番号

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(キャッシュを回避するために読み取りをオフセット)

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(キャッシュを回避するために読み取りをオフセット)

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(キャッシュを回避するために読み取りをオフセット)

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
68

あなたがしたことは、読み取り速度テストだけです。ブロックを別のデバイスに実際にコピーしている場合、他のデバイスが書き込みたいデータを受け入れている間に読み取りが一時停止します。これが発生すると、読み取りデバイス(ハードディスクの場合)で回転待ち時間の問題が発生する可能性があります。その方法で回転レイテンシが発生する頻度が減るので、HDDから1Mのチャンクを読み取る方がはるかに高速です。

copyingハードディスクの場合、bs=1Mまたはデフォルトを使用するよりもbs=4kを指定した方が高速になります。私は30〜300%の速度の改善を話している。それがあなたが毎日行うすべてでない限り、それを絶対的に最高に調整する必要はありません。ただし、デフォルトよりも良いものを選択すると、実行時間を数時間短縮できます。

実際に使用している場合は、いくつかの異なる番号を試してddプロセスにSIGUSR1シグナルを送信し、ステータスレポートを発行してステータスを確認してください。

✗ 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
28
user313114

内蔵ハードディスクに関しては、少なくとも-デバイスからブロックレイヤーを読み取る場合少なくともは、512バイトである1つのセクターを取得する必要があります。

したがって、1バイトの読み取りを処理するときは、実際にはセクター整列バイト検索でディスクから読み取っただけです。残りの511回は、キャッシュによって提供されます。

これは次のように証明できます。この例では、sdbは対象のディスクです。

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

4番目の列(読み取りをカウント)は、1バイトの読み取りを要求したにもかかわらず、1回の読み取りのみが発生したことを示しています。このデバイス(SATA 2ディスク)は最低でもセクターサイズを返す必要があるため、これは予想される動作です。カーネルは単にセクター全体をキャッシュしています。

これらのサイズのリクエストで最も重要な要素は、読み取りまたは書き込みのシステムコールを発行するオーバーヘッドです。実際、512未満の呼び出しを発行することは非効率的です。非常に大きな読み取りでは、システムコールが少なくて済みますが、そのために使用されるメモリが多くなります。

次の理由により、4096は通常、読み取り用の「安全な」番号です。

  • キャッシング(デフォルト)で読み取る場合、ページは4kです。 4k未満の読み取りでページを埋めることは、読み取りとページサイズを同じに保つよりも複雑です。
  • ほとんどのファイルシステムブロックサイズは4kに設定されています。
  • Syscallのオーバーヘッドを引き起こすのに十分な数ではありませんが(SSDの場合は現在そうです)、大量のメモリを消費するのに十分な数ではありません。
9
Matthew Ife