io_uring 没有 readahead 会怎样?
Io_uring Without Readahead
我在 Turso 数据库项目中尝试为 io_uring 后端实现 readahead 功能,结果发现差异巨大。默认使用 O_DIRECT 的 io_uring 会禁用内核预读,导致每次只提交一个 SQE,无法利用块层的请求合并,性能反而不如 syscall。开启应用层 readahead 后,虽然多提交了请求,但通过并发预读让设备接收的请求数大幅减少,平均请求尺寸显著提升。此外,我还对比了 sqpoll 线程与默认模式,发现 O_DIRECT 模式下数据直接写入用户缓冲区,绕过了内核拷贝,导致 CPU 缓存命中率下降。这篇文章深入剖析了这些底层 I/O 细节,揭示了不同配置下的性能代价。
O_DIRECT 跳过了拷贝步骤,但数据最终仍需要到达 CPU,在缓冲读取中这发生在拷贝期间,而在 O_DIRECT 模式下则表现为查询过程中的缓存未命中。