“ dd”中的“ bs”选项是否真的提高了速度?


58

我不时被告知要提高“ dd”的速度,我应该仔细选择合适的“块大小”。

即使在此处,在ServerFault上,其他人也写道:“ ...最佳块大小取决于硬件...(固有)或“ ...最佳大小将取决于您的系统总线,硬盘驱动器控制器,特定驱动器本身,以及每个驱动程序的驱动程序...(chris-s)

由于我的感觉有些不同(顺便说一句:我坚信,对bs参数进行深度调整所需的时间比所节省的时间要长得多,并且默认值是合理的),今天我就去了通过一些肮脏的基准测试。

为了降低外部影响,我决定阅读:

  • 从外部MMC卡
  • 从内部分区

和:

  • 带有相关的文件系统
  • 将输出发送到/ dev / null以避免与“写入速度”有关的问题;
  • 至少在涉及HDD时避免一些HDD缓存的基本问题。

在下表中,我报告了我的发现,读取了1GB的数据,其中包含不同的“ bs”值(您可以在此消息末尾找到原始数字):

在此处输入图片说明

基本上结果是:

  • MMC:bs = 4(是!4个字节)时,我达到了12MB / s的吞吐量。距离bs = 5及以上的最大值14.2 / 14.3不太远。

  • 硬盘:bs = 10时达到30 MB / s。肯定比默认bs = 512时的95.3 MB低,但是...也很重要。

同样,很明显,CPU的系统时间与bs值成反比(但这听起来很合理,因为bs越低,dd产生的系统调用次数就越高)。

综上所述,现在的问题是:有人可以解释(内核黑客吗?)这种吞吐量涉及的主要组件/系统是什么,是否真的值得努力指定比默认值高的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

硬盘盒-原始数字

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

11
真正好的是要具有一个bs=auto功能,dd该功能可以检测并使用设备中的最佳bs参数。

4
什么是非常不错的几个图形bs尺寸暗算速度,而不是在一个单一的问题,15个代码块。占用更少的空间,并且无限快地阅读。一张照片确实值得thoursand话。
MDMoore313 2014年

2
@BigHomie-我努力提供图表,但是...存在一些“缩放”问题。可能需要在两个轴上都使用对数刻度,...在考虑这一点时,我想这不是一个容易(且快速)解决的问题。所以我切换到“表”版本。至于“ ... 15打代码块”,我希望每个人都有机会检查“原始数字”,以避免任何(个人,我的)干扰。
Damiano Verzulli 2014年

1
@DamianoVerzulli的桌子很酷,请忽略我的喧闹声,无论如何我都给了您证明我们的迷信的赞誉,而且我第一手知道摆弄字节大小会改变速度,我也可能会回答。
MDMoore313 2014年

1
@warren-要获得4G,您也可以做,bs=8k count=512K否则bs=1M count=4K我不记得2在65536
以后的

Answers:


24

您所做的只是一个读取速度测试。如果您实际上是在将块复制到另一台设备上,而另一台设备正在接受您要写入的数据,则读取会暂停,这种情况发生时,您可能会遇到读取设备(如果是硬盘)上的旋转延迟问题,因此从HDD读取1M数据块通常会更快得多,因为这样可以减少旋转延迟。

我知道在复制硬盘时,通过指定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

2014 Macbook Pro Retina复制到USB3记忆棒,额定速度为90 MB / s写入:$ sudo dd if=~/Downloads/Qubes-R4.0-rc4-x86_64.iso of=/dev/rdisk2 status=progress显示6140928 bytes (6.1 MB, 5.9 MiB) copied, 23 s, 267 kB/s。我花了太长时间取消了它。现在指定字节大小:$ sudo dd if=~/Downloads/Qubes-R4.0-rc4-x86_64.iso of=/dev/rdisk2 bs=1M status=progress显示4558159872 bytes (4.6 GB, 4.2 GiB) copied, 54 s, 84.4 MB/s
Eric Duncan

9

关于内部硬盘,至少-从设备读取时,块层至少必须检索一个512字节的扇区。

因此,在处理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
...

第四列(对读取计数)表明,尽管您请求读取1个字节,但仅发生了1次读取。这是预期的行为,因为此设备(SATA 2磁盘)必须至少返回其扇区大小。内核只是在缓存整个扇区。

在这些大小请求中起作用的最大因素是发出用于读取或写入的系统调用的开销。实际上,发出<512的调用效率很低。很大的读取需要较少的系统调用,但这样做会占用更多的内存。

4096通常是读取的“安全”数字,因为:

  • 在具有缓存的情况下(默认)阅读时,页面为4k。用小于4k的读取填充页面比保持读取和页面大小相同要复杂得多。
  • 大多数文件系统块大小设置为4k。
  • 它的数量不足以引起系统调用开销(可能对于固态硬盘而言),但数量不足以消耗大量内存。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.