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

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

由于我的感觉有些不同(顺便说一句,我坚称深调bs参数所需的时间要比从时间上获得的增益高得多,保存,并且默认值是合理的),今天我只是通过了一些快捷基准。

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


来自外部MMC卡
来自内部分区




并已挂载相关文件系统
输出到/ dev / null以避免与“写入速度”有关的问题;
避免了HDD的一些基本问题-缓存,至少在涉及HDD时。

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



基本上出现了:


MMC:bs = 4(是的! 4个字节),我达到了12MB / s的吞吐量。距离bs = 5及以上的最大值14.2 / 14.3不太远;
HDD:bs = 10时达到30 MB / s。肯定比默认bs = 512时的95.3 MB低,但也很重要。

此外,很明显,CPU的系统时间与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



硬盘盒-原始数字

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


评论

最好的做法是在dd中具有bs = auto功能,它将检测并使用设备中的最佳bs参数。

最好的是将几个bs大小的图形与速度作图,而不是在单个问题中绘制15个代码块。占用更少的空间,并且读取速度更快。一张照片真的值得一个小时和几个字。

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

@DamianoVerzulli的桌子很酷,请忽略我的喧嚣,无论如何我都给了您证明我们的迷信的赞誉,而且我第一手知道摆弄字节大小会改变速度,我也可以将其归为答案。

我对体系结构没有很深的了解,但我认为简单的答案是,当bs <硬件块大小时,瓶颈是系统调用开销,但是当bs>硬件块大小时,瓶颈是数据传输。这就是当达到该点时吞吐量达到稳定水平的原因。

#1 楼

您所做的只是一个读取速度测试。如果您实际上是在将块复制到另一台设备,而另一台设备正在接受您要写入的数据,则读取会暂停,这种情况发生时,您可能会遇到读取设备(如果是硬盘)上的旋转延迟问题,因此通常,以这种方式减少旋转延迟时,从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字节(6.1 MB,5.9 MiB)复制,23 s,267 kB / s。我花了太长时间取消了此操作。现在指定字节大小:$ sudo dd if =〜// Downloads / Qubes-R4.0-rc4-x86_64.iso of = / dev / rdisk2 bs = 1M status = progress显示已复制4558159872字节(4.6 GB,4.2 GiB),54 s,84.4 MB /秒

–埃里克·邓肯(Eric Duncan)
18-2-10在16:10



如果有人对Mac终端感兴趣,则用于检查状态的SIGUSR1信号为CTRL + t

–ionescu77
19年12月8日10:00



#2 楼

关于内部硬盘,至少-从设备读取时,块层至少必须检索一个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。
这个数字还不够小(对于SSD来说可能是现在)导致系统调用开销,但数量不足以占用大量内存。