在 dd 中同时使用 oflag=direct 和 conv=f​​sync 可以吗?

在 dd 中同时使用 oflag=direct 和 conv=f​​sync 可以吗?

我的目标设备是 4096 bs 的硬盘。我想绕过缓存并直接或尽快写入存储。速度不是我最关心的:30 小时太多了,但 4 和 7 小时之间的差异微不足道。


我的理解(可能不是100%正确):

conv=fsync仅在调用结束时执行一次dd

但我不想将同步推迟到最后。我希望数据尽快写入存储。还有其他两个选项:oflag=directoflag=sync。我不喜欢oflag=sync,因为(1)当我测试时它非常慢bs=4096,并且(2)它仍然使用内存缓存——我认为这是不必要的。

oflag=direct绕过内核的页面缓存(内存缓存),直接写入存储。但存储本身可能将数据存储在回写 (HDD) 缓存中,因此conv=fsync仍然需要将 HDD 缓存写入实际存储。

因此,我希望可以允许——我想知道这是否理想——一起使用这两个参数,也许像这样:

dd if=/dev/zero of=/dev/sdX bs=4096 status=progress oflag=direct conv=fsync

答案1

听起来你的问题是关于速度的。您已经在使用conv=fsync,所以我认为没有安全性或“正确性”问题。除非您的硬件存在特定错误,否则您需要准确地告诉我们您的错误是什么样的。

性能的一般规则是测试你自己的情况,不要太担心微小的差异。 dd告诉你速度。您可以使用小count=.例如你可以用bs=4k count=100k400M来测试写入。


你问的是一个相对简单的案例。 /dev/zero会比你的设备快得多,所以我忽略读取性能。

使用oflag=sync将在提交每个数据块后等待所有临时缓存清空,从而失去始终保持数据传输的好处。因此,您需要指定更大的块大小以获得最佳速度,例如bs=16M

原则上,您希望一次向设备提供最多两个请求,以便它始终至少有一个请求需要处理。特别是在机械驱动器上,如果您让馈送干涸,则必须等待完整的旋转,然后才能将下一个请求写入正确的位置。 dd它本身并没有做任何事情来确保这一点。它依赖于内核或设备中的写回缓存。

oflag=direct是一个有用的中间选项。如果您遇到内核缓存问题(见下文),这是绕过该缓存的好方法。许多设备都包含自己的写回缓存,因此比相同块大小的设备oflag=direct更快。oflag=sync

内核缓存旨在正常工作,而不会减慢 IO 访问速度其他设备。例如,您同时使用的系统驱动器:-)。但这个问题有时确实会发生,人们对此有所抱怨。因此,这可能取决于您是否期待或担心这样的问题:-)。

如果您想同时尝试两个选项,请将其指定为oflag=direct,sync

即使没有oflag=sync,将块大小再增加几次也可能会降低 CPU 使用率。例如bs=16kbs=1M。但是bs=4k/bs=4096已经相当不错了,比古老的默认值要好得多bs=512

答案2

我不会打扰 -dd输入太慢了,你应该最大化任何缓存使用,因为输出非常慢。使用大块大小(以努力使用更多缓存)是您能做的最好的事情。

关于@sgon00的具体问题,dd联机帮助页说:-

fdatasync     physically write output file data before finishing            
fsync         likewise, but also write metadata

oflag=FLAGS   write as per the comma separated symbol list...

oflag=无缓存请求删除缓存。这个选项至少提到了缓存。但这并不一定意味着它会被授予。这可以与“直接”选项结合使用。

dd是一个旧程序,因此它的许多可能的参数可能无法完全按照最初的预期进行解释。

相关内容