5

我正在编写带有一些实时约束的 C 代码。我测试了我可以用 dd 写入磁盘的速度:

dd if=/dev/zero of=/dev/sdb bs=32K count=32768 oflag=direct

这会将 1GB 的零以 32K 块大小写入 /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 显示了我使用的相同打开命令。

4

2 回答 2

5

检查系统调用dd产生了什么,不仅是 open ,还有后续read的 s 和writes. 使用正确的缓冲区大小可以在这种大型副本中产生显着差异。请注意,/dev/zero如果您的最终目标是磁盘到磁盘的副本,那么这不是一个很好的基准测试。

如果你不能通过dd匹配系统调用来匹配系统调用的速度......好吧,阅读源代码。

于 2010-08-13T19:00:02.910 回答
0

我将留下关于将系统调用与其他人匹配的部分。这个答案是关于缓冲部分的。

尝试对您使用的缓冲区大小进行基准测试。尝试一系列值。

在学习 Java 时,我编写了一个简单的“复制”克隆,然后尝试匹配它的速度。由于代码逐字节读取/写入缓冲区大小是真正产生影响的原因。我自己没有缓冲它,但我要求读取获取给定大小的块。块越大,速度越快——达到一定程度。

至于使用 32K 块大小,请记住操作系统仍然为用户模式进程使用单独的 IO 缓冲区。即使您正在使用特定硬件做某事,即您正在为具有某些物理限制的设备编写驱动程序,例如具有扇区大小的 CD-RW 驱动器,块大小只是故事的一部分。操作系统也会有它的缓冲区。

于 2010-08-13T19:21:16.877 回答