有时我在网上看到这样的评论:“确保设置‘bs=’,因为默认值会花费太长时间”,以及我自己极其不科学的经历,“这似乎比其他方法花费的时间更长”。上周时间”似乎证实了这一点。因此,每当我使用“dd”(通常在 1-2GB 范围内)时,我都会确保指定 bytes 参数。大约一半的时间我使用我从中复制的任何在线指南中指定的值;其余时间,我将从“fdisk -l”列表中选择一些有意义的数字,用于我认为较慢的介质(例如我正在写入的 SD 卡)。
对于给定的情况(媒体类型、总线大小或其他重要的因素),有没有办法确定“最佳”值?容易判断吗?如果没有,有没有一种简单的方法可以达到 90-95% 的目标?或者“只选择比 512 更大的东西”就是正确答案吗?
我想过自己尝试一下这个实验,但是(除了需要做很多工作之外)我不确定哪些因素会影响答案,所以我不知道如何设计一个好的实验。
答案1
只有一种方法可以确定最佳块大小,这就是基准。我刚刚做了一个快速基准测试。测试机器是运行 Debian GNU/Linux 的 PC,内核为 2.6.32,coreutils 8.5。涉及的两个文件系统都是硬盘分区上 LVM 卷上的 ext3。源文件大小为 2GB(准确地说是 2040000kB)。启用缓存和缓冲。每次运行之前,我都会使用 清空缓存sync; echo 1 >|/proc/sys/vm/drop_caches
。运行时间不包括最终sync
刷新缓冲区;最终的sync
时间约为 1 秒。
运行same
是同一文件系统上的副本;运行diff
是复制到不同硬盘上的文件系统。为了保持一致性,报告的时间是通过实用程序获得的挂钟时间time
,以秒为单位。我只运行每个命令一次,所以我不知道时间上有多少差异。
same diff
t (s) t (s)
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
结论:大块大小(几兆字节)会有所帮助,但效果并不显着(比我对同一驱动器副本的预期小很多)。并且cat
表现cp
不要那么差。有了这些数字,我觉得不dd
值得费心。一起去吧cat
!
答案2
dd
回溯到需要转换旧 IBM 大型机磁带时,块大小必须与用于写入磁带的块大小相匹配,否则数据块将被跳过或截断。 (9 磁道磁带很挑剔。很高兴它们已经死了。)现在,块大小应该是设备扇区大小的倍数(通常为 4KB,但在最近的磁盘上可能要大得多,并且在非常小的拇指上)驱动器可能更小,但 4KB 是一个合理的中间立场,无论如何)并且越大性能越好。我经常在硬盘上使用 1MB 块大小。 (这些天我们也有更多的内存可以使用。)
答案3
我同意极客龙的回答大小应该是块大小的倍数,通常是 4K。
如果你想找到块大小stat -c "%o" filename
可能是最简单的选择。
但说你这样做dd bs=4K
,那就意味着它确实read(4096); write(4096); read(4096); write(4096)
......
每个系统调用都涉及上下文切换,这会涉及一些开销,并且根据 I/O 调度程序,带有散布写入的读取可能会导致磁盘执行大量查找。 (对于 Linux 调度程序来说,这可能不是一个主要问题,但仍然值得考虑。)
因此,如果您这样做bs=8K
,则允许磁盘一次读取两个块,这些块可能在磁盘上靠近在一起,然后再寻找其他地方进行写入(或为另一个进程提供 I/O 服务)。
按照这个逻辑,bs=16K
甚至更好,等等。
所以我想知道的是,是否存在性能开始变差的上限,或者是否仅受内存限制。
答案4
如果没有,有没有一种简单的方法可以达到 90-95% 的目标?
使用bs=1M
它将为您超过 85% 的设备提供超过 95% 的最佳性能,从慢速 USB2/3 闪存驱动器、SD 卡和硬盘驱动器到 NVMe SSD,甚至仅 RAM 设备(例如/dev/zero
.
来源?
我脑子里有声音。
还有一些十多年的实证测试,加上伪科学的基准测试和有偏见的常识。
嘿,你问的是简单的方式!