零拷贝(Zero Copy)

目录

零拷贝(Zero Copy)

1.什么是Zero Copy?

2.物理内存和虚拟内存

3.内核空间和用户空间

4.Linux的I/O读写方式

4.1 I/O中断原理

4.2 DMA传输原理

5.传统I/O方式

5.1传统读操作

5.2传统写操作

6.零拷贝

6.1.用户态直接IO

6.2.mmap+write

6.3. sendfile

6.4. sendfile+DMA gather copy

6.5 splice

7.Linux零拷贝对比

8.零拷贝具体应用实现


零拷贝(Zero Copy)

1.什么是Zero Copy?

零拷贝技术指的是在计算机执行操作时,CPU不需要先将数据从一个内存区域复制到另一个内存区域,从而可以减少上下文以及CPU的拷贝时间。

他的作用是在数据报从网络设备到用户程序空间传递的过程,减少数据拷贝的次数,减少系统调用,实现CPU的零参与,彻底消除CPU在这方面的负载,实现零拷贝的最主要的技术就是DMA数据传输技术内存区域映射技术

  • 零拷贝就是可以减少数据在用户缓冲区和内核缓冲区之间的反复的I/O拷贝操作。

  • 零拷贝机制可以减少用户进程地址空间和内核地址空间之间因为上下文切换带来的CPU开销。

为什么线程切换会导致用户态与内核台的切换?  
因为线程的调度是在内核态运行的,而线程中的代码是在用户态运行。

2.物理内存和虚拟内存

由于操作系统的CPU和内存是共享的,因此需要一套完整的内存管理机制防止内存泄漏的问题。现代操作系统提供了一种对主存的抽象概念:既是虚拟内存,虚拟内存为每个进程提供了一个一致的,私有的地址空间,让每个进程都产生了一种自己独享主存的错觉。

3.内核空间和用户空间

操作系统的内核空间是独立于普通的程序的空间,可以访问显卡等受保护的资源也可以访问底层硬件的设备的权限。是为了防止用户直接操作内核,保证系统安全。操作系统将虚拟内存划分为两部分,一部分是内核空间,一部分是用户空间。

Linux系统中,内核模块运行在内核空间,对应的进程处于内核态;用户进程运行在用户空间,对应的进程是用户态。

4.Linux的I/O读写方式

Linux提供了轮询,I/O中断,DMA传输三中国主存之间的数据传输协议。

  • 轮询:是基于死循环对I/O端口进行不断检测。

  • I/O中断:是指的是数据到达时,磁盘主动向CPU发起中断请求,CPU自身负责数据的传输。

  • DMA传输:是指数据到达后由DMA负责数据的传输拷贝,完成后通知CPU。

4.1 I/O中断原理

在DMA出现之间,应用程序与磁盘之间的I/O操作都是磁盘发起CPU中断,每次用户进程读取磁盘时,都需要CPU中断,然后发起IO请求等待数据的读取与拷贝完成,每次的IO中断都会导致CPU的上下文切换。(不太理解)

流程:

  1. 用户进程向CPU发起read()系统调用,由用户态转换为内核态,然后一直阻塞等待数据的返回。

  2. CPU发接受到指令后发起IO请求,磁盘将数据放入磁盘控制器缓冲区中。

  3. 数据准备完成后磁盘向CPU发起IO中断信号。

  4. CPU接收到IO中断后将磁盘控制器缓冲区的数据拷贝到内核缓冲区,再将数据从内核缓冲区拷贝到用户缓冲区。

  5. 用户进程由内核态转换为用户态,解除阻塞状态,等待CPU的下一个执行时间钟。

4.2 DMA传输原理

DMA的全称叫直接内存访问(Direct Memory Access),是一种允许外围设备直接访问主存的机制。也就是说基于DMA访问方式,系统主内存于磁盘和显卡之间的数据传输可以绕开CPU的全程调度,目前大多数硬件设备包括磁盘控制器,网卡,显卡,以及声卡都支持DMA技术.

整个数据在传输操作在一个DMA控制器的控制下进行的。CPU除了在数据开始传输和结束时做一点处理外,在传输的过程中CPU可以继续进行其他工作。这样大部分时间里,CPU计算和I/O操作都属于并行操作。使得效率大大提升。

  1. 用户态发起read()系统调用,进入内核态,用户态线程阻塞。

  1. CPU发起IO请求通知DMA,DMA发起IO请求给磁盘,磁盘将数据加载到磁盘控制器缓冲,通知DMA,DMA将磁盘控制器中的数据拷贝到内核缓冲区中。DMA发出数据读完信号。

  2. CPU将数据从内核缓冲区读取到用户缓冲区,之后read()系统调用完之后回到用户态,恢复就绪准备获取时间片后执行。

5.传统I/O方式

对于传统的IO操作的数据读写流程,整个过程涉及2次CPU拷贝,2次DMA拷贝,四次上下文切换。

  • 上下文切换:用户程序发起系统调用后,CPU会将用户程序从用户态切换到内核态;系统调用结束返回后,cpu从内核态切换回用户态。

  • CPU拷贝:数据的传输依靠CPU处理,数据拷贝一直占据CPU的资源。

  • DMA拷贝:数据通知DMA磁盘控制器下达指令,让DMA控制器控制数据的传输,数据传输完毕后再把信息反馈给CPU,减轻CPU的占用率。

5.1传统读操作

传统的读操作会进行2次系统调用,1次CPU传输,1次DMA拷贝。

  1. 用户态通过read系统调用进入内核态,

  2. CPU利用DMA控制器,将数据从主存或硬盘拷贝到内核空间的读缓冲区

  3. CPU再将读内核缓冲区拷贝到用户缓冲区。

  4. 上下文切换回到用户态,read调用执行返回。

5.2传统写操作

同理。

6.零拷贝

用户态直接I/O: 应用程序直接访问硬件存储,操作系统只是辅助数据传输,这种方式依旧存在上下文切换,只不过硬件的数据不经过内核缓冲区。因此直接IO不存在内核空间到用户空间的CPU拷贝。

如下图:

减少拷贝次数:在数据传输过程中,避免数据在用户空间和内核空间的CPU拷贝,以及数据在内核空间的CPU拷贝。这时当前主流的零拷贝技术的实现思路。

写时复制技术:写时复制技术,是当多个进程读取一块数据的时候,不需要拷贝操作,当某个进程要修改数据,那么需要拷贝到自己的进程空间中。

6.1.用户态直接IO

用户通过直接IO使用用户态的库函数直接访问硬件设备。数据跨过内核传输。如果内核极大提高性能。

用户态直接IO只能适用于不需要内核缓冲区的应用程序,这写应用程序通常在进程地址空间有自己的数据缓冲机制,称为自缓存应用程序。如数据库管理系统。

其次,这种零拷贝机制会直接操作磁盘I/O,由于CPU和磁盘I/O之间的执行时间差距,会造成大量资源浪费,解决方案是配合异步IO。

6.2.mmap+write

一种零拷贝是使用mmap+write替换原来的read+write的方式,减少了一次CPU拷贝操作。mmap是Linux提供的一种内存映射文件的方式,将一个进程的虚拟内存地址映射到磁盘文件地址。

mmap+write的伪代码:
​
tmp_buf=mmap(file_fd,len);
​
write(socket,tmp_buf,len);

使用mmap的方式就是将内核缓冲区的地址与用户缓冲区的地址进行映射,从而实现内核缓冲区到用户缓冲区的内存共享。省去数据从内核缓冲区拷贝到用户缓冲区的过程。

基于mmap+write系统调用的零拷贝技术。整个拷贝过程会发生4次上下文切换,一次CPU拷贝,2次DMA拷贝。

用户进程读写数据流程如下:

  1. 用户进程通过mmap函数向内核发起系统调用,由用户态切换为内核态。

  2. 将用户缓冲区和内核缓冲区进行mmap地址映射。

  3. CPU利用DMA拷贝数据从磁盘或主存到内核的读缓冲区。

  4. 上下文切换回到用户态,mmap系统调用返回。

  5. 用户进程通过wirte向内核发起系统调用,上下文从用户态切换为内核态。

  6. CPU将读缓冲区的数据拷贝到网络缓冲区。

  7. CPU利用DMA控制器将数据从网络缓冲区拷贝到网卡,进行数据传输。

  8. 上下文从内核态切换回用户态,wirte系统调用结束返回。

优点

针对大文件可以极大的提高IO性能,但是对于小文件,内存映射反而会导致碎片空间的浪费。

6.3. sendfile

sendfile系统调用是Linux2.1引入的目的简化网络通过两个通道之间的数据传输过程。sendfile系统调用的引用减少了两次上下文切换。

伪代码如下:
​
•   sendfile(socket_fd,file_fd,len);

通过sendfile的系统调用,数据可以直接在内核空间进行IO传输,省区了用户空间和内核空间来回拷贝。与mmap不同的是,sendfile调用IO数据对于用户空间来说是完全不可见的,也就是一次完全意义上的数据传输过程。

基于sendfile系统调用的零拷贝技术,整个拷贝过程会发生2次上下文切换,一次CPU拷贝,两次DMA拷贝。

流程如下:

  1. 用户进程通过sendfile函数向内核发起系统调用,上下文切换进入内核态。

  2. CPU利用DMA将主存或磁盘数据拷贝到内核空间的读缓冲区。

  3. CPU的内核读缓冲区拷贝数据到网络缓冲区socket buffer

  4. CPU利用DMA将数据从网络缓冲区传输到网卡。

  5. 系统上下文切换用户态。之后sendfile系统调用结束返回。

相较于mmap内存映射的方式,sendfile减少了两次系统调用,但仍有一次CPU拷贝操作。

sendfile存在的问题就是用户进程不能对数据进行修改(压缩,加密),只能丹村的完成一次数据传输

6.4. sendfile+DMA gather copy

Linux 2.4 版本的内核对sendfile系统调用进行修改,为DMA拷贝引入了gather操作。

他将内核空间的读缓冲区中对应的数据描述信息(内存地址,地址偏移量)记录到相应的网络缓冲区中,

由DMA根据内存地址,地址偏移量将数据批量从读缓冲区拷贝到网卡,这样就省去了内核空间仅剩的一次CPU拷贝操作。

sendfile的伪代码如下:
​
sendfile(socket_fd,file_fd,len)

基于sendfile+DMA gather copy系统拷贝,整个拷贝过程会发生2次上下文切换,0次CPU拷贝以及2次DMA拷贝。

流程如下:

  1. 用户进程发起sendfile函数系统调用向内核,上下文切换到内核态。

  2. CPU利用DMA将数据从主存或磁盘缓冲区拷贝到内核缓冲区。

  3. CPU将读缓冲区的文件描述符和文件长度拷贝到网络缓冲区

  4. 基于已经拷贝到文件描述符和文件长度,CPU利用DMA控制器的gather /scatter操作直接批量的从内核的读缓冲区拷贝到网卡进行数据传输。

  5. 上下文切换从内核态切换用户态,sendfile系统调用执行返回

这种拷贝方式同样存在用户进程不能对数据进行修改的问题,而且本身需要硬件的支持,只适用于将数据从文件拷贝到socket套接字上的传输过程。

6.5 splice

sendfile只适用于将数据从文件拷贝到socket套接字上,同时支持硬件的传输。这也限定了它的使用范围。

Linux2.6.17版本引入了splice系统调用,不仅不需要系统硬件的支持,还实现了文件描述符之间的数据零拷贝(就是C:->D:)

splice的伪代码
​
splice(fd_in,off_in,fd_out,off_out,len,flags);

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

基于splice系统调用的零拷贝方式,整个拷贝过程会发生2次上下文切换,0次CPU拷贝以及2次DMA拷贝。

流程:

  1. 用户进程通过splice函数向内核发起系统调用,上下文从用户态切换为内核态。

  2. CPU利用DMA将数据从磁盘或主存中拷贝到内核的读缓冲区中。

  3. CPU在内核的读缓冲区与socket缓冲区建立管道(pipeline)

  4. CPU利用DMA控制器,将数据从网络缓冲区拷贝到网卡进行传输。

  5. 上下文切换从内核切换回到用户态,splice系统调用执行结束。

7.Linux零拷贝对比

无论是传统的IO拷贝方式还是引入了零拷贝,2次DMA Copy都是少不了的,因为两次DMA都是依赖硬件完成的,下面从CPU拷贝次数,DMA拷贝次数,以及系统调用几个方面总结上述io拷贝的差别:

拷贝方式CPU拷贝DMA拷贝系统调用上下文切换
传统方式read+write22read/write4
内存映射mmap+write12mmap/write4
sendfile12sendfile2
sendfile+DMA gather copy02sendfile2
splice02splice2

8.零拷贝具体应用实现

  • Java NIO零拷贝

    • 基于内存映射的(mmap) 方式 MappedByteBuffer

    • 基于sendfile方式的FileChannel

  • Netty 零拷贝

  • RocketMQ 和 Kafka 零拷贝

    • RocketMq选择了mmap+write这种零拷贝方式,适用于业务级别的小块文件持久化和传输

    • 而Kafka采用的sendfile这种零拷贝,适用于系统日志消息这种高吞吐量的大文件的数据持久化和传输。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/843041.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

免费使用知网下载文献

第一步:输入网址:https://digi.library.hb.cn:8443/#/(或搜索湖北省图书馆) 第二步:点击登录按钮。 第三步:使用手机 支付宝 扫描页面左侧二维码。 第四步:手机点击“电子读者证注册”。&…

抖音 v27.8.0 内置增强模块,自动播放、无水印下载(可登录,助手增强版)

介绍 抖音应用作为全球领先的短视频平台,其内置功能允许用户将喜欢的内容保存至本地设备,但默认情况下,这些视频会带有抖音的水印。为了解决这一限制,该版本使用户能够直接保存不带水印的视频到手机中,无需使用任何第…

R25 型双极型晶体管 433功率放大器,集电极电流可达100mA

R25 型硅基微波双极型晶体管是一种常见的晶体管,主要用于高频电子放大线路中。常被用作放大器、开关、变频器等电子电路中的核心元件。在放大电路中,它可以将微弱的信号放大到足以驱动输出负载;在开关电路中,它可以实现电路的打开…

易查分小程序 学生成绩管理小程序

亲爱的老师们,是不是每次成绩公布后,家长们的连环夺命call让你头大?担心孩子们的成绩信息安全,又想快速分享给家长,这可咋整?别急,易查分小程序来帮忙啦! 安全有保障 智能验证码&a…

基于tcp实现自定义应用层协议

认识协议 协议(Protocol) 是一种通信规则或标准,用于定义通信双方或多方之间如何交互和传输数据。在计算机网络和通信系统中,协议规定了通信实体之间信息交换的格式、顺序、定时以及有关同步等事宜的约定。简易来说协议就是通信…

【Linux】Linux下centos更换国内yum源

🌱博客主页:青竹雾色间 🌱系列专栏:Linux 😘博客制作不易欢迎各位👍点赞⭐收藏➕关注 目录 1. 备份旧的 YUM 源文件2. 下载国内的 YUM 源文件阿里云:网易: 3. 清理 YUM 缓存4. 更新…

scp问题:Permission denied, please try again.

我把scp归纳三种情况: 源端root——》目标端root 源端root——》目标端mysql(任意)用户 源端(任意用户)——》目标端root用户 在scp传输文件的时候需要指导目标端的用户密码,如root用户密码、mysql用户…

选择海外代理IP需要注意什么?

跨境电商近年来的兴起与发展,越来越多的跨境从业者从事该行业,但在从事跨境贸易中则需要海外IP代理来突破地域限制、提升访问速度和稳定性、防止账号关联以及保护隐私和安全。这些功能都有助于跨境电商企业在全球范围内拓展业务,提升竞争力&a…

一文搞定jdk8升级到jdk11

一、背景 为什么要升级JDK11 性能 JDK11的G1的GC性能高很多,对比JDK8无论是性能还是内存占比都有很大的提升,业内各项数据指标也都表明JDK11的G1在应对突发流量的下的效果惊人; 版本兼容 Spring Boot 2.7.x及以后的版本将不再支持Java 8作为…

【IC】partial good

假设单core良率80%,core pass 数量分布呈二项分布。 16个core全pass的概率为: 有n个core pass的概率为: 分布如下: 当np>5且nq>5时,二项分布近似服从正态分布

python fstring教程(f-string教程)(python3.6+格式化字符串方法)

文章目录 Python F-String 教程:深度探究与实用指南引言基础用法什么是F-String?表达式嵌入 格式化选项小数点精度宽度与对齐数字格式化 高级用法复杂表达式调用函数多行F-String嵌套格式化 总结 Python F-String 教程:深度探究与实用指南 引言 在Pyt…

中间件是什么?信创中间件有哪些牌子?哪家好用?

当今社会,中间件的重要性日益凸显,尤其是在信创背景下,选择适合的中间件产品对于推动企业数字化转型和升级具有重要意义。今天我们就来聊聊中间件是什么?信创中间件有哪些牌子?哪家好用?仅供参考哈&#xf…

山东大学软件学院项目实训-创新实训-基于大模型的旅游平台(二十二)- 微服务(2)

目录 4. Ribbon负载均衡 4.1 负载均衡流程 4.2 负载均衡策略 4.3 Ribbon饥饿加载 5. Nacos注册中心 5.1 服务注册到nacos 5.2 nacos服务分级存储模型 5.3 根据权重负载均衡 5.4 环境隔离--namespace 4. Ribbon负载均衡 4.1 负载均衡流程 4.2 负载均衡策略 默认实现是…

cesium绘制区域编辑

npm 安装也是可以的 #默认安装最新的 yarn add cesium#卸载插件 yarn remove cesium#安装指定版本的 yarn add cesium1.96.0#安装指定版本到测试环境 yarn add cesium1.96.0 -D yarn install turf/turf <template><div id"cesiumContainer"></div&…

大学理科生搜题软件?分享四个软件和公众号,来对比看看吧 #笔记#知识分享

在快节奏的大学生活中&#xff0c;合理利用这些日常学习工具&#xff0c;能够让你事半功倍&#xff0c;提高学习效率。 1.福昕翻译 可以一键翻译文档内容&#xff0c;并提供还原排版的译文&#xff0c;对经常看外文文献的朋友来说&#xff0c;绝对是福音 福昕翻译是一流专业…

设计模式基础——设计原则介绍

1.概述 ​ 对于面向对象软件系统的设计而言&#xff0c;如何同时提高一个软件系统的可维护性、可复用性、可拓展性是面向对象设计需要解决的核心问题之一。面向对象设计原则应运而生&#xff0c;这些原则你会在设计模式中找到它们的影子&#xff0c;也是设计模式的基础。往往判…

HTML大雪纷飞

目录 写在前面 HTML简介 完整代码 代码分析 运行结果 系列文章 写在后面 写在前面 小编又又又出现啦&#xff01;这次小编给大家带来大雪纷飞HTML版&#xff0c;不需要任何的环境&#xff0c;只要有一个浏览器&#xff0c;就可以随时随地下一场大雪哦&#xff01; HTM…

Diffusion Model, Stable Diffusion, Stable Diffusion XL 详解

文章目录 Diffusion Model生成模型DDPM概述向前扩散过程前向扩散的逐步过程前向扩散的整体过程 反向去噪过程网络结构训练和推理过程训练过程推理过程优化目标 详细数学推导数学基础向前扩散过程反向去噪过程 Stable Diffusion组成结构运行流程网络结构变分自编码器 (VAE)文本编…

富港银行 邀请码 兑换码 优惠码 分享

首次记得一定要扫码注册&#xff0c;扫码注册开户费50美金&#xff0c;每笔26美金手续费&#xff0c;目前能接收CBI银行资金的有&#xff1a;工行、交通、中行&#xff0c;请知悉 cbi帐户管理费&#xff1a;10美元/月&#xff0c;余额>500美元&#xff0c;1美元/月/&#x…

在vue中实现下载文件功能

实际操作为&#xff0c;在表格中 我们可以获取到文件的id&#xff0c;通过插槽就可以实现 <template #default"scope"><el-button type"text" click"handleDown(scope.row)"><span>下载</span></el-button> </…