我正在编写带有一些实时约束的C代码。我测试了用dd写入磁盘的速度:
dd if = / dev / zero of = / dev / sdb bs = 32K count = 32768 oflag = direct
这会将32GB块大小的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显示了我使用的相同开放命令。
答案 0 :(得分:5)
检查dd
调用的系统调用,而不仅仅是打开,还包括后续的read
和writes
。使用正确的缓冲区大小可以在这种大型副本中产生显着差异。请注意,如果您的最终目标是磁盘到磁盘副本,则/dev/zero
不适合进行基准测试。
如果你不能通过匹配系统调用的系统调用来匹配dd
的速度......那么,请阅读源代码。
答案 1 :(得分:0)
我要离开关于将系统调用与其他人匹配的部分。这个答案是关于缓冲部分的。
尝试对您使用的缓冲区大小进行基准测试。尝试一系列值。
在学习Java时,我写了一个简单的'copy'克隆,然后尝试匹配它的速度。由于代码执行逐字节读/写操作,因此缓冲区大小确实有所不同。我自己并没有缓冲它,但我要求读取取一个给定大小的块。块越大,它越快 - 达到一定程度。
至于使用32K块大小,请记住操作系统仍然为用户模式进程使用单独的IO缓冲区。即使您正在使用特定硬件执行某些操作,即您正在为具有某些物理限制的设备编写驱动程序,例如一个扇区大小的CD-RW驱动器,块大小只是故事的一部分。操作系统也会有缓冲区。