土法炼钢兴趣小组的算法知识备份

【操作系统百科】异步 I/O 模型 benchmark

文章导航

分类入口
os
标签入口
#benchmark#epoll#io-uring#libaio#async-model

目录

epoll 还是 io_uring?SQPOLL 值不值得?libaio 在 O_DIRECT 下到底比 io_uring 差多少?用数据说话。

一、先看图

flowchart TD
    WORKLOAD[统一 Workload] --> ECHO[Echo Server<br/>网络小包]
    WORKLOAD --> STATIC[静态文件服务<br/>混合大小]
    WORKLOAD --> DBIO[数据库 I/O<br/>O_DIRECT 随机读写]

    ECHO --> M1[epoll LT]
    ECHO --> M2[epoll ET]
    ECHO --> M3[io_uring]
    ECHO --> M4[io_uring SQPOLL]

    DBIO --> M5[libaio]
    DBIO --> M6[io_uring]
    DBIO --> M7[同步 pread + 线程池]

    classDef wl fill:#388bfd22,stroke:#388bfd,color:#adbac7;
    classDef model fill:#3fb95022,stroke:#3fb950,color:#adbac7;
    class WORKLOAD,ECHO,STATIC,DBIO wl
    class M1,M2,M3,M4,M5,M6,M7 model

二、方法论

2.1 变量控制

2.2 硬件参考

以下数据来自公开 benchmark(Jens Axboe、io_uring mailing list):

三、Echo Server(网络场景)

3.1 模型

客户端发 64 字节 → 服务器 echo 回来。1000 并发连接。

3.2 结果趋势

模型 QPS(万) p99 延迟 CPU 占用
epoll LT ~80 ~120μs
epoll ET ~85 ~110μs
io_uring ~95 ~90μs
io_uring SQPOLL ~100 ~80μs 高(轮询线程)

3.3 分析

四、静态文件服务(混合 I/O)

4.1 模型

HTTP GET 混合大小文件(1KB-1MB),1000 并发。

4.2 结果趋势

模型 吞吐(Gbps) 小文件 p99 大文件 p99
epoll + sendfile ~8 ~200μs ~5ms
io_uring splice ~9 ~180μs ~4ms
io_uring fixed buf ~10 ~150μs ~3.5ms

4.3 分析

io_uring 的注册 buffer 和 fixed file 在高吞吐场景收益明显。

五、数据库 I/O(O_DIRECT 随机读)

5.1 模型

4KB 随机读,O_DIRECT,队列深度 128。

5.2 结果趋势

模型 IOPS(万) p99 延迟
同步 pread + 线程池 ~30 ~200μs
libaio ~45 ~80μs
io_uring ~50 ~60μs
io_uring IOPOLL ~55 ~40μs

5.3 分析

六、SQPOLL 开销分析

SQPOLL 专用一个内核线程持续轮询 SQ ring。

SQPOLL idle CPU 开销
无请求 ~100% 一个核
idle_timeout 10ms 低负载时接近 0

生产建议:开启 sq_thread_idle(默认 1000ms)。

七、syscall 开销量化

操作 syscall 次数/IO
epoll_wait + read/write 2-3
io_uring(普通) ~0.5(批量 submit + 批量 wait)
io_uring SQPOLL 0(纯 ring 操作)

每次 syscall 约 100-300ns → 高频场景差距显著。

八、何时选择哪种模型

flowchart TD
    START[新项目] --> Q1{需要文件 I/O?}
    Q1 -- 是 --> URING[io_uring]
    Q1 -- 否 --> Q2{连接数 >10K?}
    Q2 -- 是 --> Q3{需要极致延迟?}
    Q3 -- 是 --> URING
    Q3 -- 否 --> EPOLL[epoll]
    Q2 -- 否 --> EPOLL

    classDef choice fill:#f0883e22,stroke:#f0883e,color:#adbac7;
    classDef result fill:#3fb95022,stroke:#3fb950,color:#adbac7;
    class START,Q1,Q2,Q3 choice
    class URING,EPOLL result

九、注意事项

十、小结


参考文献

工具


上一篇splice/tee/vmsplice 下一篇Linux 内核内存模型

同主题继续阅读

把当前热点继续串成多页阅读,而不是停在单篇消费。

2026-05-18 · os

【操作系统百科】io_uring 内核内部

io_uring 用共享内存 ring buffer 实现零 syscall 异步 I/O——SQ/CQ、SQPOLL、IOPOLL、注册 fd/buffer、multishot、安全模型演化。本文深入内核实现与工程实践。

2026-05-17 · os

【操作系统百科】POSIX AIO 与 libaio

Linux 有两套异步 I/O——glibc POSIX AIO(线程池伪装)和内核 libaio(io_submit/io_getevents,限制重重)。本文讲两者实现、O_DIRECT 约束、io_cancel 不可用性、与 epoll 的不可组合问题。

2026-05-19 · os

【操作系统百科】epoll 内部

epoll 用红黑树管理 fd、就绪链表 O(1) 返回事件——打败 select/poll 的关键。本文讲 eventpoll 结构、LT/ET 语义、EPOLLEXCLUSIVE 与惊群、级联 epoll、EPOLLONESHOT、与 io_uring 的比较。

2026-05-15 · os

【操作系统百科】FUSE

FUSE 把文件系统实现搬到用户态——开发快、崩溃不影响内核。本文讲 FUSE 协议、/dev/fuse 通信、FUSE_PASSTHROUGH、virtio-fs、io_uring FUSE、性能天花板与优化策略。


By .