深入理解掌握零拷贝技术
前言
零拷贝技术是指计算机执行操作时,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拷贝,其具体过程如下:
- 应用进程调用 mmap() ,DMA 会把磁盘的数据拷贝到内核的缓冲区里,应用进程跟操作系统内核「共享」这个缓冲区
- 应用进程再调用 write(),操作系统直接将内核缓冲区的数据拷贝到 socket 缓冲区中,这一切都发生在内核态,由 CPU 来搬运数据
- 最后,把内核的 socket 缓冲区里的数据,拷贝到网卡的缓冲区里,这个过程是由 DMA 搬运的
显然仅仅减少一次数据拷贝,依然难以满足要求
sendfile
如上图所属,sendfile技术传输文件,需要进行2次用户态和内核态的切换,3次数据拷贝(1次CPU拷贝、两次DMA拷贝)
相对于mmap,其又减少了两次上下文的切换,具体过程如下:
- 应用调用sendfile接口,传入文件描述符,应用程序切换至内核态,并通过 DMA 将磁盘上的数据拷贝到内核缓冲区中
- CPU将缓冲区数据拷贝至Socket缓冲区
- 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拷贝)
具体过程如下:
- 通过 DMA 将磁盘上的数据拷贝到内核缓冲区里;
- 缓冲区描述符和数据长度传到 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拷贝),具体过程如下:
- 用户进程通过 splice() 函数向内核(kernel)发起系统调用,上下文从用户态(user space)切换为内核态(kernel space)。
- CPU 利用 DMA 控制器将数据从主存或硬盘拷贝到内核空间(kernel space)的读缓冲区(read buffer)。
- CPU 在内核空间的读缓冲区(read buffer)和网络缓冲区(socket buffer)之间建立管道(pipeline)。
- CPU 利用 DMA 控制器将数据从网络缓冲区(socket buffer)拷贝到网卡进行数据传输。
- 上下文从内核态(kernel space)切换回用户态(user space),splice 系统调用执行返回。
splice 拷贝方式也同样存在用户程序不能对数据进行修改的问题。除此之外,它使用了 Linux 的管道缓冲机制,可以用于任意两个文件描述符中传输数据,但是它的两个文件描述符参数中有一个必须是管道设备
总结
本文简单介绍了 Linux 中的几种 Zero-copy 技术,随着技术的不断发展,又出现了诸如:写时复制、共享缓冲等技术,本文就不再赘述。
广义的来讲,Linux 的 Zero-copy 技术可以归纳成以下三大类:
- 减少甚至避免用户空间和内核空间之间的数据拷贝:在一些场景下,用户进程在数据传输过程中并不需要对数据进行访问和处理,那么数据在 Linux 的 Page Cache 和用户进程的缓冲区之间的传输就完全可以避免,让数据拷贝完全在内核里进行,甚至可以通过更巧妙的方式避免在内核里的数据拷贝。这一类实现一般是是通过增加新的系统调用来完成的,比如 Linux 中的 mmap(),sendfile() 以及 splice() 等。
- 绕过内核的直接 I/O:允许在用户态进程绕过内核直接和硬件进行数据传输,内核在传输过程中只负责一些管理和辅助的工作。这种方式其实和第一种有点类似,也是试图避免用户空间和内核空间之间的数据传输,只是第一种方式是把数据传输过程放在内核态完成,而这种方式则是直接绕过内核和硬件通信,效果类似但原理完全不同。
- 内核缓冲区和用户缓冲区之间的传输优化:这种方式侧重于在用户进程的缓冲区和操作系统的页缓存之间的 CPU 拷贝的优化。这种方法延续了以往那种传统的通信方式,但更灵活。
深入理解掌握零拷贝技术相关推荐
- 重新深入理解零拷贝技术
点击上方"朱小厮的博客",选择"设为星标" 后台回复"书",获取 后台回复"k8s",可领取k8s资料 注意事项:除了 ...
- 从根上理解高性能、高并发(二):深入操作系统,理解I/O与零拷贝技术
1.系列文章引言 1.1 文章目的 作为即时通讯技术的开发者来说,高性能.高并发相关的技术概念早就了然与胸,什么线程池.零拷贝.多路复用.事件驱动.epoll等等名词信手拈来,又或许你对具有这些技术特 ...
- 面试题:如何理解 Linux 的零拷贝技术?
点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 本文讲解 Linux 的零拷贝技术,云计算是一门很庞大的技术学科, ...
- 大白话讲解 零拷贝技术
数据的四次拷贝与四次上下文切换 很多应用程序在面临客户端请求时,可以等价为进行如下的系统调用: 1. File.read(file, buf, len); 2. Socket.send(socket, ...
- 计算机IO系列「一」零拷贝技术
深入剖析Linux IO原理和几种零拷贝机制的实现 转载自:深入剖析Linux IO原理和几种零拷贝机制的实现 - 知乎 前言 零拷贝(Zero-copy)技术指在计算机执行操作时,CPU 不需要先将 ...
- 关于零拷贝技术,你了解多少?
点击关注公众号,实用技术文章及时了解 来源:github.com/Spongecaptain/ SimpleClearFileIO 注意事项:除了 Direct I/O,与磁盘相关的文件读写操作都有使 ...
- 零拷贝技术在 Java 中为何这么牛?
[CSDN 编者按]大家在学计算机的过程中是否会遇到"零拷贝"这样的字眼,本文针对这一技术为大家提供详细的概念解释,并对其产出的意义及其在Java中的应用进行说明. 责编 | 欧阳 ...
- Linux - 零拷贝技术
Linux - 零拷贝技术 前言 一. 相关概念 1.1 缓冲区 1.1.1 内核缓冲区 1.1.2 用户缓冲区 1.2 DMA技术 1.3 虚拟内存 二. 零拷贝 2.1 传统文件传输流程 2.2 ...
- 什么是零拷贝技术(Zero Copy)?
千里之行,始于足下 什么是"零拷贝"技术 要想要了解"零拷贝"机制,首先要了解在什么地方会用到这个东西.试想一个场景:我们需要从磁盘读取一个文件,然后通过网络输 ...
最新文章
- python反转链表和成对反转
- rsync文件实时同步_从文件同步rsync算法谈起
- Python之爬虫-段子网
- int(a) 和 (int ) a 及 数据存储地址的探究
- shell win10 改成cmd_win10系统必做优化,让你的电脑告别卡顿,运行速度至少提升20%...
- EMNLP 2021 投稿FAQ
- MVPArms MVP+Dagger+Rxjava+Retrofit快速集成框架
- 怎么查看c语言库文件,C语言函数库和文件
- php 按指定长度分割字符串,php实现将字符串按照指定距离进行分割的方法
- cada0图纸框_CAD怎么画图纸框?cad图纸框的绘制方法
- vue学习笔记二:HBuilder X框架搭建
- DirectX11 交换链是什么
- 职业生涯自我规划五步
- 免费制作字体软件 - FontForge
- 第三天,【1124】接口,注册,登录
- 国嵌Linux视频驱动开发
- Linux input 子系统详解
- 首都师范 博弈论 4 1 1三人博弈的纳什均衡
- 高速版的股票数据源增加复权功能,股票量化分析工具QTYX-V2.3.3
- 2017App Store 最新完整版审核指南
热门文章
- 惠普178nw芯片清零_惠普打印加粉后怎么清零?别再找了,这才是正确的
- 《青春》--塞缪尔·厄尔曼
- visio多树枝直角加箭头_零基础国画教程:树枝基本画法详解,简单易学,小白也能学会!...
- 医院智能3D蓝牙导航导诊系统
- 计算机与智能化专业课程,计算机与人工智能专业方向课程大纲介绍-Artificial Intelligence 人工智能(原创)...
- kingedit 上传php_JS文件上传神器bootstrap fileinput详解
- OpenCV学习-P34-P38 Opencv边缘检测
- 我的世界服务器修改原版血量,我的世界服务器MythicMobs插件教程技能编写血量限制与触发几率...
- 数学空间 Space
- 云队友丨替刘强东花钱的人