前言

零拷贝技术是指计算机执行操作时,CPU不需要先将数据从某处内存复制到另一个特定区域。这种技术通常用于通过网络传输文件时节省CPU周期和内存带宽。

原始的网络请求,需要数次在用户态和内核态之间切换以及数据的拷贝,这无疑大大影响了处理的效率,零拷贝技术就是为解决这一问题而诞生的。

我们常见的高性能组件(Netty、Kafka等),其内部基本都应用了零拷贝,在学习这些组件之前,有必要先了解什么是零拷贝。

推荐视频:

C++架构师学习地址:C/C++Linux服务器开发高级架构师/Linux后台架构师

零拷贝的实现,用户态协议栈ntytcp

手写用户态协议栈,udpipeth数据包的封装,零拷贝的实现,柔性数组

传统文件传输 read + write

DMA拷贝:指外部设备不通过CPU而直接与系统内存交换数据的接口技术

如上图所示,传统的网络传输,需要进行4次用户态和内核态切换,4次数据拷贝(2次CPU拷贝,2次DMA拷贝)

上下文的切换涉及到操作系统,相对CPU速度是非常耗时的,而且仅仅一次文件传输,竟然需要4次数据拷贝,造成CPU资源极大的浪费

不难看出,传统网络传输涉及很多冗余且无意义的操作,导致应用在高并发情况下,性能指数级下降,表现异常糟糕

为了解决这一问题,零拷贝技术诞生了,他其实是一个抽象的概念,但其本质就是通过减少上下文切换和数据拷贝次数来实现的

mmap + write

如上图所示,mmap技术传输文件,需要进行4次用户态和内核态切换,3次数据拷贝(1次CPU拷贝、两次DMA拷贝)

相对于传统数据传输,mmap减少了一次CPU拷贝,其具体过程如下:

  1. 应用进程调用 mmap() ,DMA 会把磁盘的数据拷贝到内核的缓冲区里,应用进程跟操作系统内核「共享」这个缓冲区
  2. 应用进程再调用 write(),操作系统直接将内核缓冲区的数据拷贝到 socket 缓冲区中,这一切都发生在内核态,由 CPU 来搬运数据
  3. 最后,把内核的 socket 缓冲区里的数据,拷贝到网卡的缓冲区里,这个过程是由 DMA 搬运的

显然仅仅减少一次数据拷贝,依然难以满足要求

sendfile

如上图所属,sendfile技术传输文件,需要进行2次用户态和内核态的切换,3次数据拷贝(1次CPU拷贝、两次DMA拷贝)

相对于mmap,其又减少了两次上下文的切换,具体过程如下:

  1. 应用调用sendfile接口,传入文件描述符,应用程序切换至内核态,并通过 DMA 将磁盘上的数据拷贝到内核缓冲区中
  2. CPU将缓冲区数据拷贝至Socket缓冲区
  3. DMA将数据拷贝到网卡的缓冲区里,应用程序切换至用户态

sendfile其实是将原来的两步读写操作进行了合并,从而减少了2次上下文的切换,但其仍然不是真正意义上的“零”拷贝

文章福利:现在C++程序员面临的竞争压力越来越大。那么,作为一名C++程序员,怎样努力才能快速成长为一名高级的程序员或者架构师,或者说一名优秀的高级工程师或架构师应该有怎样的技术知识体系,这不仅是一个刚刚踏入职场的初级程序员,也是工作三五年之后开始迷茫的老程序员,都必须要面对和想明白的问题。为了帮助大家少走弯路,技术要做到知其然还要知其所以然。以下视频获取点击:C++架构师学习资料

如果想学习C++工程化、高性能及分布式、深入浅出。性能调优、TCP,协程,Nginx源码分析Nginx,ZeroMQ,MySQL,Redis,MongoDB,ZK,Linux内核,P2P,K8S,Docker,TCP/IP,协程,DPDK的朋友可以看一下这个学习地址:C/C++Linux服务器开发高级架构师/Linux后台架构师https://ke.qq.com/course/417774?flowToken=1013189

sendfile + SG-DMA

从 Linux 内核 2.4 版本开始起,对于支持网卡支持 SG-DMA 技术的情况下, sendfile() 系统调用的过程发生了点变化,如上图所示,sendfile + SG-DMA技术传输文件,需要进行2次用户态和内核态的切换,2次数据拷贝(1次DMA拷贝,1次SG-DMA拷贝)

具体过程如下:

  1. 通过 DMA 将磁盘上的数据拷贝到内核缓冲区里;
  2. 缓冲区描述符和数据长度传到 socket 缓冲区,这样网卡的 SG-DMA 控制器就可以直接将内核缓存中的数据拷贝到网卡的缓冲区里,此过程不需要将数据从操作系统内核缓冲区拷贝到 socket 缓冲区中,这样就减少了一次数据拷贝;

此种方式对比之前的,真正意义上去除了CPU拷贝,CPU 的高速缓存再不会被污染了,CPU 可以去执行其他的业务计算任务,同时和 DMA 的 I/O 任务并行,极大地提升系统性能。

但他的劣势也很明显,强依赖于硬件的支持

splice

Linux 在 2.6.17 版本引入 splice 系统调用,不再需要硬件支持,同时还实现了两个文件描述符之间的数据零拷贝。

splice 系统调用可以在内核空间的读缓冲区(read buffer)和网络缓冲区(socket buffer)之间建立管道(pipeline),从而避免了用户缓冲区和Socket缓冲区的 CPU 拷贝操作。

基于 splice 系统调用的零拷贝方式,整个拷贝过程会发生 2次用户态和内核态的切换,2次数据拷贝(2次DMA拷贝),具体过程如下:

  1. 用户进程通过 splice() 函数向内核(kernel)发起系统调用,上下文从用户态(user space)切换为内核态(kernel space)。
  2. CPU 利用 DMA 控制器将数据从主存或硬盘拷贝到内核空间(kernel space)的读缓冲区(read buffer)。
  3. CPU 在内核空间的读缓冲区(read buffer)和网络缓冲区(socket buffer)之间建立管道(pipeline)。
  4. CPU 利用 DMA 控制器将数据从网络缓冲区(socket buffer)拷贝到网卡进行数据传输。
  5. 上下文从内核态(kernel space)切换回用户态(user space),splice 系统调用执行返回。

splice 拷贝方式也同样存在用户程序不能对数据进行修改的问题。除此之外,它使用了 Linux 的管道缓冲机制,可以用于任意两个文件描述符中传输数据,但是它的两个文件描述符参数中有一个必须是管道设备

总结

本文简单介绍了 Linux 中的几种 Zero-copy 技术,随着技术的不断发展,又出现了诸如:写时复制、共享缓冲等技术,本文就不再赘述。

广义的来讲,Linux 的 Zero-copy 技术可以归纳成以下三大类:

  • 减少甚至避免用户空间和内核空间之间的数据拷贝:在一些场景下,用户进程在数据传输过程中并不需要对数据进行访问和处理,那么数据在 Linux 的 Page Cache 和用户进程的缓冲区之间的传输就完全可以避免,让数据拷贝完全在内核里进行,甚至可以通过更巧妙的方式避免在内核里的数据拷贝。这一类实现一般是是通过增加新的系统调用来完成的,比如 Linux 中的 mmap(),sendfile() 以及 splice() 等。
  • 绕过内核的直接 I/O:允许在用户态进程绕过内核直接和硬件进行数据传输,内核在传输过程中只负责一些管理和辅助的工作。这种方式其实和第一种有点类似,也是试图避免用户空间和内核空间之间的数据传输,只是第一种方式是把数据传输过程放在内核态完成,而这种方式则是直接绕过内核和硬件通信,效果类似但原理完全不同。
  • 内核缓冲区和用户缓冲区之间的传输优化:这种方式侧重于在用户进程的缓冲区和操作系统的页缓存之间的 CPU 拷贝的优化。这种方法延续了以往那种传统的通信方式,但更灵活。

深入理解掌握零拷贝技术相关推荐

  1. 重新深入理解零拷贝技术

    点击上方"朱小厮的博客",选择"设为星标" 后台回复"书",获取 后台回复"k8s",可领取k8s资料 注意事项:除了 ...

  2. 从根上理解高性能、高并发(二):深入操作系统,理解I/O与零拷贝技术

    1.系列文章引言 1.1 文章目的 作为即时通讯技术的开发者来说,高性能.高并发相关的技术概念早就了然与胸,什么线程池.零拷贝.多路复用.事件驱动.epoll等等名词信手拈来,又或许你对具有这些技术特 ...

  3. 面试题:如何理解 Linux 的零拷贝技术?

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 本文讲解 Linux 的零拷贝技术,云计算是一门很庞大的技术学科, ...

  4. 大白话讲解 零拷贝技术

    数据的四次拷贝与四次上下文切换 很多应用程序在面临客户端请求时,可以等价为进行如下的系统调用: 1. File.read(file, buf, len); 2. Socket.send(socket, ...

  5. 计算机IO系列「一」零拷贝技术

    深入剖析Linux IO原理和几种零拷贝机制的实现 转载自:深入剖析Linux IO原理和几种零拷贝机制的实现 - 知乎 前言 零拷贝(Zero-copy)技术指在计算机执行操作时,CPU 不需要先将 ...

  6. 关于零拷贝技术,你了解多少?

    点击关注公众号,实用技术文章及时了解 来源:github.com/Spongecaptain/ SimpleClearFileIO 注意事项:除了 Direct I/O,与磁盘相关的文件读写操作都有使 ...

  7. 零拷贝技术在 Java 中为何这么牛?

    [CSDN 编者按]大家在学计算机的过程中是否会遇到"零拷贝"这样的字眼,本文针对这一技术为大家提供详细的概念解释,并对其产出的意义及其在Java中的应用进行说明. 责编 | 欧阳 ...

  8. Linux - 零拷贝技术

    Linux - 零拷贝技术 前言 一. 相关概念 1.1 缓冲区 1.1.1 内核缓冲区 1.1.2 用户缓冲区 1.2 DMA技术 1.3 虚拟内存 二. 零拷贝 2.1 传统文件传输流程 2.2 ...

  9. 什么是零拷贝技术(Zero Copy)?

    千里之行,始于足下 什么是"零拷贝"技术 要想要了解"零拷贝"机制,首先要了解在什么地方会用到这个东西.试想一个场景:我们需要从磁盘读取一个文件,然后通过网络输 ...

最新文章

  1. python反转链表和成对反转
  2. rsync文件实时同步_从文件同步rsync算法谈起
  3. Python之爬虫-段子网
  4. int(a) 和 (int ) a 及 数据存储地址的探究
  5. shell win10 改成cmd_win10系统必做优化,让你的电脑告别卡顿,运行速度至少提升20%...
  6. EMNLP 2021 投稿FAQ
  7. MVPArms MVP+Dagger+Rxjava+Retrofit快速集成框架
  8. 怎么查看c语言库文件,C语言函数库和文件
  9. php 按指定长度分割字符串,php实现将字符串按照指定距离进行分割的方法
  10. cada0图纸框_CAD怎么画图纸框?cad图纸框的绘制方法
  11. vue学习笔记二:HBuilder X框架搭建
  12. DirectX11 交换链是什么
  13. 职业生涯自我规划五步
  14. 免费制作字体软件 - FontForge
  15. 第三天,【1124】接口,注册,登录
  16. 国嵌Linux视频驱动开发
  17. Linux input 子系统详解
  18. 首都师范 博弈论 4 1 1三人博弈的纳什均衡
  19. 高速版的股票数据源增加复权功能,股票量化分析工具QTYX-V2.3.3
  20. 2017App Store 最新完整版审核指南

热门文章

  1. 惠普178nw芯片清零_惠普打印加粉后怎么清零?别再找了,这才是正确的
  2. 《青春》--塞缪尔·厄尔曼
  3. visio多树枝直角加箭头_零基础国画教程:树枝基本画法详解,简单易学,小白也能学会!...
  4. 医院智能3D蓝牙导航导诊系统
  5. 计算机与智能化专业课程,计算机与人工智能专业方向课程大纲介绍-Artificial Intelligence 人工智能(原创)...
  6. kingedit 上传php_JS文件上传神器bootstrap fileinput详解
  7. OpenCV学习-P34-P38 Opencv边缘检测
  8. 我的世界服务器修改原版血量,我的世界服务器MythicMobs插件教程技能编写血量限制与触发几率...
  9. 数学空间 Space
  10. 云队友丨替刘强东花钱的人