核心内容摘要
2026年华为HCIE数通认证考试,可以在哪里看课程?
简单来说“零拷贝”Zero-copy并不是指数据真的物理上一次都不拷贝而是指消除在内核态Kernel Space与用户态User Space之间冗余的数据拷贝以及减少 CPU 参与拷贝的工作。
在传统的 I/O 操作中数据往往要在内核缓冲区和用户缓冲区之间跳来跳去这不仅浪费内存带宽还让 CPU 忙于搬砖。
为了让你看清这些“骚操作”我们先看传统的 I/O 流程再逐一拆解零拷贝的各种实现。
传统 I/O 的痛点Baseline传统的readwrite操作流程如下DMA 拷贝磁盘 - 内核缓冲区Page Cache。
CPU 拷贝内核缓冲区 - 用户缓冲区应用程序内存。
CPU 拷贝用户缓冲区 - Socket 缓冲区。
DMA 拷贝Socket 缓冲区 - 网卡NIC。
代价4 次上下文切换User/Kernel 切换4 次数据拷贝其中 2 次 CPU 亲自下场。
零拷贝技术全家桶① mmap write内存映射这是最早期的改进方案。
既然用户空间和内核空间来回拷贝麻烦那就直接把内核缓冲区映射到用户空间。
原理使用mmap()系统调用让用户进程的虚拟地址指向内核空间的 Page Cache 地址。
过程DMA 拷贝磁盘 - 内核缓冲区。
内核与用户共享不需要 CPU 拷贝到用户空间。
CPU 拷贝内核缓冲区 - Socket 缓冲区。
DMA 拷贝Socket 缓冲区 - 网卡。
优点减少了 1 次 CPU 拷贝。
缺点依然有 4 次上下文切换且在大并发下可能触发SIGBUS错误如果文件被另一个进程截断。
② sendfileLinux
1 版本引入这是真正意义上迈向“零”的一大步。
原理在一个系统调用内完成数据传输不再经过用户空间。
过程DMA 拷贝磁盘 - 内核缓冲区。
CPU 拷贝内核缓冲区 - Socket 缓冲区。
DMA 拷贝Socket 缓冲区 - 网卡。
优点2 次上下文切换(因为是一个接口 少了mmap结束返回用户态和再调用write进入内核态过程)3 次拷贝1 次 CPU 拷贝。
③ sendfile DMA Gather Copy真正的零 CPU 拷贝这是sendfile的增强版需要网卡硬件支持。
原理内核不再把数据拷贝到 Socket 缓冲区而是只把数据的**内存地址和长度描述符**拷贝过去。
网卡的 DMA 控制器直接根据这些描述符从内核缓冲区抓取数据。
过程DMA 拷贝磁盘 - 内核缓冲区。
描述符拷贝内核将位置信息传给 Socket 缓冲区极小开销。
DMA 收集拷贝网卡直接从内核缓冲区读数据。
优点2 次上下文切换2 次拷贝0 次 CPU 拷贝。
④ spliceLinux
2.
17 引入它不像sendfile只能发文件到 Socket它更通用。
原理利用“管道Pipe”机制。
它在两个文件描述符之间移动数据而不经过用户空间。
特点要求传输的两个描述符中至少有一个必须是管道。
效果实现了内核空间的“原生”数据流转避免了 CPU 拷贝。
⑤ Direct I/O直接 I/O严格来说这叫“绕过缓存”也是零拷贝的一种思路。
原理应用程序直接访问磁盘跳过操作系统的 Page Cache内核缓冲区。
适用场景数据库如 MySQL/Oracle。
它们通常有自己的缓存管理机制不希望 OS 帮倒忙。
缺点如果数据不在 App 的缓存里每次都要读磁盘性能反而可能下降。
⑥ MSG_ZEROCOPYLinux
14 以后引入的高级特性主要针对 Socket 发送。
原理利用写时复制Copy-on-Write技术。
应用层发送数据时内核不拷贝数据而是修改页表引用。
适用场景超大数据包发送通常 10KB 才有收益否则页表维护开销可能盖过拷贝开销。
⑦ RDMARemote Direct Memory Access这是“终极方案”属于硬件级别的零拷贝。
原理通过特定的网卡让一台机器可以直接读写另一台机器的内存完全绕过双方的 CPU 和操作系统内核。
适用场景高性能计算HPC、分布式存储如 NVMe-over-Fabrics。