当前位置: 首页 > news >正文

【Linux】Linux 零拷贝技术全景解读:从内核到硬件的性能优化之道

学麻了,以下内容来自【腾讯元宝】。

Linux 零拷贝技术全景解读:从内核到硬件的性能优化之道

传统I/O的性能瓶颈:为什么需要零拷贝?

在深入探讨各种零拷贝技术之前,我们首先要理解传统I/O操作(即使用 readwrite 系统调用,并涉及用户空间指针 user_ptr)为何会成为性能瓶颈。

当需要读取一个文件并通过网络发送时,传统方式会触发以下步骤:

  1. read 系统调用:用户进程发起读取请求,导致从用户态切换到内核态(第1次上下文切换)。
  2. DMA拷贝:DMA控制器将数据从磁盘拷贝到内核缓冲区(第1次DMA拷贝,无CPU参与)。
  3. CPU拷贝:CPU将数据从内核缓冲区拷贝到 user_ptr 所指向的用户缓冲区(第1次CPU拷贝)。随后,系统从内核态切换回用户态(第2次上下文切换)。
  4. write 系统调用:用户进程发起写入请求,导致用户态再次切换到内核态(第3次上下文切换)。
  5. CPU拷贝:CPU将数据从用户缓冲区拷贝到socket缓冲区(第2次CPU拷贝)。
  6. DMA拷贝:DMA控制器将数据从socket缓冲区拷贝到网卡(第2次DMA拷贝)。最后,内核态切换回用户态(第4次上下文切换)。

这个过程包含了 4次上下文切换2次CPU拷贝2次DMA拷贝。其中,两次CPU拷贝(内核缓冲区 ↔ 用户缓冲区)消耗了宝贵的CPU周期,仅仅是为了搬运数据,而非处理业务逻辑。在高性能网络编程、大数据处理等I/O密集型场景中,这无疑是巨大的性能损耗。

零拷贝技术的演进与核心机制

零拷贝技术的核心目标就是减少甚至消除不必要的CPU数据拷贝,从而降低CPU占用、提升吞吐量、减少延迟。其实现并非单一技术,而是一系列在不同层面、针对不同场景的优化方案。

1. mmap:内存映射

mmap 通过内存映射技术,将内核缓冲区直接映射到用户进程的地址空间。这样,应用程序就可以像操作普通内存一样直接访问文件数据,从而避免了 read 调用所引发的那一次从内核到用户的CPU拷贝。

  • 工作流程

    1. 调用 mmap 建立映射关系。
    2. 数据通过DMA从磁盘拷贝到内核缓冲区(第1次DMA拷贝)。
    3. 用户进程通过映射后的虚拟地址直接操作内核缓冲区中的数据,无需额外拷贝。
    4. 调用 write 时,数据仍需从内核缓冲区CPU拷贝到socket缓冲区(1次CPU拷贝)。
    5. 数据最终通过DMA从socket缓冲区拷贝到网卡(第2次DMA拷贝)。
  • 优势:减少了1次CPU拷贝,适合需要对文件内容进行修改的场景(如日志处理)。

  • 局限:仍有4次上下文切换和1次CPU拷贝;大文件映射可能导致内存占用过高。

2. sendfile:内核级数据搬运工

sendfile 系统调用允许数据在内核空间内直接从文件描述符传输到socket描述符,完全绕过用户空间。这消除了 mmap + write 方式中仍存在的一次CPU拷贝和两次上下文切换。

  • 工作流程(基础版)

    1. 调用 sendfile(out_fd, in_fd, ...)
    2. 数据通过DMA从磁盘拷贝到内核缓冲区。
    3. 数据从内核缓冲区CPU拷贝到socket缓冲区
    4. 数据通过DMA从socket缓冲区拷贝到网卡。
      这个过程只有2次上下文切换1次CPU拷贝
  • 工作流程(优化版:DMA Gather Copy)
    这是 sendfile 的终极形态。当底层硬件(如网卡)支持分散-聚集(Scatter-Gather) 功能时,可以实现真正的零CPU拷贝

    1. 调用 sendfile
    2. 数据通过DMA从磁盘拷贝到内核缓冲区。
    3. CPU不再拷贝数据本身,而是将数据在内存中的位置和信息(描述符)传递给网卡。
    4. 支持Gather功能的DMA控制器,根据这些描述符信息,直接从内核缓冲区读取数据并发送到网络(第2次DMA拷贝)。
      这个过程实现了 0次CPU拷贝2次DMA拷贝,是效率最高的文件到网络传输方式。
  • 优势:极大减少了上下文切换和CPU拷贝,甚至实现零CPU拷贝。

  • 局限:数据对用户进程不可见,无法修改;通常只能用于文件到socket的传输。

3. splice:基于管道的通用零拷贝

splice 是另一个零拷贝系统调用,它不要求硬件特殊支持,而是利用管道作为中转站,在内核中移动数据。

  • 工作流程

    1. 调用 splice,将数据从源(如文件)引入一个管道。
    2. 再次调用 splice,将数据从管道导向目标(如socket)。
      整个过程数据始终在内核中流动,实现了0次CPU拷贝
  • 优势:纯软件实现,不依赖硬件;可用于任意两个文件描述符(但至少有一个必须是管道)。

  • 局限:两个文件描述符中必须有一个是管道。

4. DMA-BUF:设备间的零拷贝桥梁

前述技术主要优化的是数据在“内核-用户”之间或内核内部的流动。而 DMA-BUF 解决的则是一个更为核心的问题:如何在不同硬件设备(如GPU、摄像头、编码器)之间高效地共享大量数据,而无需CPU参与拷贝

  • 核心思想:DMABUF 是 Linux 内核中用于在不同设备驱动或子系统之间共享内存缓冲区的框架。它通过一个文件描述符(fd) 来代表一块缓冲区。这个fd可以在进程间或驱动间传递,但数据本身始终停留在物理内存的同一位置。

  • 工作流程

    1. 导出:一个设备驱动(生产者,如GPU)分配一块缓冲区,并将其“导出”为一个DMABUF对象,获得一个fd。
    2. 传递:这个fd可以通过IPC(如Unix域套接字)传递给另一个设备驱动或进程(消费者,如显示驱动器)。
    3. 导入:消费者通过fd“导入”这个DMABUF,获得直接访问该缓冲区的权限。
      这样,渲染好的图像数据就能从GPU直接送往显示器,全程无需CPU进行繁重的数据拷贝。
  • 关键优势

    • 真正的跨设备零拷贝:实现了设备到设备的直接DMA传输。
    • 内置同步机制:提供 dma_fence 等机制,确保硬件操作的有序性(如等GPU渲染完,显示器再读取)。
    • 标准化框架:统一了Linux内核中图形、视频等子系统的缓冲区共享方式。
  • 典型应用:现代显示系统(Wayland)、摄像头到GPU再到编码器的多媒体流水线等。

下面的表格清晰地汇总了这几种核心技术的对比。

技术核心原理数据拷贝 (CPU / DMA)上下文切换关键优势典型应用场景
传统 I/O数据在用户缓冲区和内核缓冲区间显式来回拷贝。2次 / 2次4次编程简单,数据可处理。通用I/O。
mmap + write将内核缓冲区映射到用户空间,进程直接访问。1次 / 2次4次减少1次CPU拷贝,可处理数据。处理大文件、需修改数据的场景。
sendfile数据在内核空间直接从文件传输到socket。1次 (基础) / 0次 (优化) / 2次2次避免用户空间参与,高效。静态Web服务器(Nginx默认启用)。
sendfile + GatherDMA控制器根据描述符直接从内核缓冲区聚合数据发送。0次 / 2次2次真正的零CPU拷贝,需要硬件支持。高性能文件传输。
splice利用管道在内核中连接两个文件描述符。0次 / 2次2次不依赖硬件,可用于任意fd(至少一管道)。流式处理、数据转发。
DMA-BUF通过文件描述符(fd)在不同设备间共享同一块缓冲区。0次 (设备间) / 视情况而定视情况而定实现跨设备零拷贝,硬件同步。摄像头→GPU→显示器的多媒体流水线。

实践总结:如何选择零拷贝技术?

了解各种技术原理后,关键在于如何根据实际场景做出选择:

  • 需要对数据进行处理或修改:选择 mmap。它允许你像操作内存一样处理文件数据,是数据库等应用的常见选择。
  • 纯文件转发,追求极致性能:选择 sendfile。这是静态资源服务器(如Nginx)的首选,尤其是在支持DMA Gather Copy的系统上,性能最高。
  • 需要在内核空间进行灵活的数据搬运:选择 splice。当数据需要在非普通文件描述符(如管道)之间流动时,它是理想工具。
  • 数据在多个硬件加速器之间流动:这是 DMA-BUF 的专属领域。在涉及GPU、视频编解码器等多媒体图形处理时,必须使用此方案。(作者注:之前做Jetson零拷贝就是用这种方法。)

希望这篇整合的文章能够帮助你构建起对Linux零拷贝技术全面而清晰的认识。如果你对某个具体技术的实现细节或应用场景有更深入的疑问,我们可以继续探讨。

参考资料

  • 一文让你彻底搞清楚,Linux零拷贝技术的那些事儿:这里面的图很清晰
http://www.dtcms.com/a/490793.html

相关文章:

  • 微软ML.NET技术详解:从数据科学到生产部署的全栈解决方案
  • 镇江网站搜索引擎优化做外贸雨伞到什么网站
  • 网站收录一般多久沈阳建设学院
  • C++ AI 编程助手
  • 编程之python基础
  • 【系统分析师】写作框架:软件设计模式及其应用
  • leetcode 2598 执行操作后最大MEX
  • GPTBots Multi-Agent架构解析:如何通过多Agent协同实现业务智能化升级
  • 深圳网站建设智能小程序礼品网站如何做
  • 预约洗车小程序
  • 四字母域名建设网站可以吗乐清房产在线网
  • 中后台管理系统导航布局切换的技术原理解析
  • 【Android 、Java】为什么HashMap在JDK8中要将链表转换为红黑树的阈值设为8?这个数字是如何确定的?
  • Django中处理多数据库场景
  • 建设信源网站全国分类信息网站排名
  • MathType延时使用
  • Vue3 基础语法全解析:从入门到实战的核心指南
  • 莆田建站服务相馆网站建设费用预算
  • shell编程语言---数组函数
  • 黑马点评学习笔记02(Mabatis—plus)
  • 晶体管的定义,晶体管测量参数和参数测量仪器
  • 网站建设需要报告2345网址导航app
  • Java 设计模式——工厂模式:从原理到实战的系统指南
  • VTK实战:vtkSurfaceReconstructionFilter——从点云到三维表面的重建利器
  • 基于微信小程序的篮球场馆预订系统【2026最新】
  • java基础 之 Hash家族_哈希冲突
  • 算法--双指针二
  • RK3576开发板/核心板应用分享之开源鸿蒙
  • 公司网站页脚外包公司的业务员
  • [crackme]028-ArturDents-CrackMe#3