DIRECT I/O与页缓存IO性能测试结果异常原因咨询
测试结果反常的核心原因及原理说明
1. 测试代码存在的问题
你首次测试的结果反常,核心是测试设计和工具使用存在三处明显缺陷:
- 计时方式错误:你用
clock()统计的是进程消耗的CPU时间,而非实际运行的墙上时间(Wall Time)。DIRECT IO的进程大部分时间处于IO等待状态,几乎不消耗CPU;而普通IO需要进行内核态页缓存到用户态缓冲区的内存拷贝,会占用大量CPU时间,用clock()统计天然会放大普通IO的耗时,测试结果没有参考意义。正确的计时应该使用clock_gettime(CLOCK_MONOTONIC)统计实际运行时间。 - 缓存状态未控制:测试前没有清空系统页缓存,且你先测试DIRECT IO再测试普通IO的顺序,也会导致缓存状态不一致,进一步干扰测试结果。标准的IO测试前需要执行
echo 3 > /proc/sys/vm/drop_caches清空所有缓存,且每次测试单独执行,避免前序测试的影响。 - 文件预分配问题:你在
lay_file中仅使用ftruncate调整文件大小,没有实际写入数据,首次读文件时会触发磁盘块分配逻辑,额外增加耗时。
2. 大缓冲区下DIRECT IO更快的原理
当使用100MB大块读时,DIRECT IO的性能优势来自于省掉了大额的内存拷贝开销:
普通IO的读路径是存储设备→内核页缓存→用户态缓冲区,需要两次数据拷贝,你连续读取100次100MB的文件,累计需要拷贝10GB数据从内核态到用户态,内存拷贝的速度通常在1020GB/s左右,仅这部分开销就会消耗0.51秒的时间。
而DIRECT IO跳过页缓存,路径是存储设备→用户态缓冲区,仅需要一次拷贝,再加上NVMe SSD的顺序读性能极强,高端NVMe的顺序读性能可以达到10GB/s以上,直接读存储的开销反而低于内存拷贝的开销,因此会出现DIRECT IO更快的测试结果。
同时大块顺序读可以被IO栈合并为大请求下发给SSD,SSD对连续大请求的处理效率非常高,操作系统页缓存的预读等优化在这种场景下收益极低,无法抵消内存拷贝的额外开销。
3. 小缓冲区下普通IO更快的原理
当缓冲区调整为4KB时,数据拷贝的开销变得极低,此时页缓存的优势得以体现:
普通IO只需要从内存的页缓存中拷贝4KB数据到用户态,耗时可以忽略;而DIRECT IO每次都要走完整的存储IO路径,发起SSD读请求,哪怕NVMe SSD延迟很低,内核IO栈的处理开销也远高于小内存拷贝的开销,因此普通IO性能更好,符合理论预期。
补充测试注意事项
- 关闭CPU节能、睿频功能,避免CPU频率波动影响计时结果
- 多次重复测试取平均值,降低单次测试的随机误差
- 测试时避免其他进程占用磁盘或内存资源,减少干扰
内容的提问来源于stack exchange,提问作者Pranav Bhandari
相关产品推荐
相关产品推荐

