无法达到 dd 的速度
我正在编写具有一些实时约束的 C 代码。我测试了使用 dd 写入磁盘的速度:
dd if=/dev/zero of=/dev/sdb bs=32K count=32768 oflag=direct
这将以 32K 块大小将 1GB 的零写入 /dev/sdb
我达到了大约 103 MB/s
现在我以编程方式执行类似的操作:
open("/dev/sdb",O_WRONLY|O_CREAT|O_DIRECT|O_TRUNC, 0666);
我得到一个时间戳值 从 32K 缓冲区写入 /dev/sdb 10,000 次(在 for 循环中) 获取另一个时间戳值 进行一些数字运算以获得以 MB/s 为单位的速率,大约为 49 MB/s
为什么我不能达到与 dd 相同的速度? strace 显示了我使用的相同打开命令。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我将把有关匹配系统调用的部分留给其他人。这个答案是关于缓冲部分的。
尝试对您使用的缓冲区大小进行基准测试。尝试一系列值。
在学习 Java 时,我编写了一个简单的“copy”克隆,然后尝试匹配它的速度。由于代码是逐字节读/写的,所以缓冲区大小才是真正造成差异的原因。我自己没有缓冲它,但我要求读取获取给定大小的块。块越大,速度就越快——直到一定程度。
至于使用 32K 块大小,请记住操作系统仍然为用户模式进程使用单独的 IO 缓冲区。即使您正在使用特定的硬件进行某些操作,即您正在为具有某些物理限制的设备(例如具有扇区大小的 CD-RW 驱动器)编写驱动程序,块大小也只是问题的一部分。操作系统仍然会有它的缓冲区。
I'm leaving the part about matching the system calls to somebody else. This answer is about the buffering part.
Try benchmarking the buffer size you use. Experiment with a range of values.
When learning Java, I wrote a simple clone of 'copy' and then tried to match it's speed. Since the code did byte-by-byte read/writes the buffer size was what really made the difference. I wasn't buffering it myself but I was asking the read to fetch chunks of a given size. The bigger the chunk, the faster it went - up to a point.
As for using 32K block size, remember that the OS still uses separate IO buffers for user-mode processes. Even if you are doing something with specific hardware, i.e. you're writing a driver for a device that has some physical limitation, e.g. a CD-RW drive with sector sizes, the block size is only part of the story. The OS will still have it's buffer too.
检查
dd
进行了哪些系统调用,不仅是打开,还包括后续的read
和writes
。使用正确的缓冲区大小可以在这种大型副本中产生显着的差异。请注意,如果您的最终目标是磁盘到磁盘的复制,那么/dev/zero
并不是一个很好的基准测试。如果您无法通过将系统调用与系统调用相匹配来匹配 dd 的速度...那么,请阅读源代码。
Check what system calls
dd
makes, not just the open but also the subsequentread
s andwrites
. Using the right buffer sizes can make a significant difference in this kind of large copy. Note that/dev/zero
is not a good test for benchmarking if your final goal is a disk-to-disk copy.If you can't match
dd
's speed by matching it system call for system call... well, read the source.