什么是零拷贝 、零拷贝优化方案 - 真正的零拷贝,哪些地方会用到零拷贝技术

news2024/11/28 20:39:59

文章目录

      • 什么是零拷贝
        • 3、零拷贝优化方案 - 真正的零拷贝
        • 哪些地方会用到零拷贝技术

现在来谈谈零拷贝,以及在开发中哪些地方使用到零拷贝。
开干…

什么是零拷贝

零拷贝指的是,从一个存储区域到另一个存储区域的copy任务无需CPU参与就可完成。零拷贝的底层是
通过DMA总线技术实现的。零拷贝与具体的编程语言无关,完全依赖于OS,OS支持就可使用,不支持
设置了也不起作用。
DMA(Direct Memory Access,直接内存访问)是一种计算机系统内部的数据传输技术,需要DMA总
线(硬件的体系结构)的硬件支持。其整个数据传输过程是在DMA控制器下完成的。
零拷贝在计算机内部数据拷贝及网络传输中都大量使用,用于减少CPU消耗和内存带宽占用,减少用户
空间与内核空间的拷贝过程,减少用户态与内核态间的切换次数,提高系统效率,提升系统性能。例如
远程服务器处理客户端浏览器的主页打开请求过程,就是一个零拷贝在网络传输中的典型应用。下面全
部以该场景为例进行分析。

在这里插入图片描述

现在我们可以看到1->2->3->4的整个过程一共经历了四次拷贝的方式,**但是真正消耗资源和浪费时间的是第二次和第三次,因为这两次都需要经过我们的CPU拷贝,而且还需要内核态和用户态之间的来回切换。**想想看,我们的CPU资源是多么宝贵,要处理大量的任务。还要去拷贝大量的数据。如果能把CPU的这两次拷贝给去除掉,岂不快哉!!!既能节省CPU资源,还可以避免内核态和用户态之间的切换。

这里还要先说一下用户态和内核态的区别:

  • 处于用户态执行时,进程所能访问的内存空间和对象受到限制,其所处于占有的处理器是可被抢占的
  • 处于内核态执行时,则能访问所有的内存空间和对象,且所占有的处理器是不允许被抢占的。

在这里插入图片描述

现在一看,感觉性能资源都得到了很大的提升,不过现在还不并不是完美的。因为这三次拷贝还用到了CPU的拷贝技术,就是第二次。不过不要担心。Linux开发人员比我们更加深谋远虑。

3、零拷贝优化方案 - 真正的零拷贝

在Linux2.4 内核做了优化,取而代之的是只包含关于数据的位置和长度的信息的描述符被追加到了socket buffer 缓冲区中。DMA引擎直接把数据从内核缓冲区传输到协议引擎(protocol engine),从而消除了最后一次CPU copy。经过上述过程,数据只经过了2次copy就从磁盘传送出去了。这个才是真正的Zero-Copy

注意:这里的零拷贝其实是根据内核状态划分的,在这里没有经过CPU的拷贝,数据在用户态的状态下,经历了零次拷贝,所以才叫做零拷贝,但不是说不拷贝。

在这里插入图片描述

哪些地方会用到零拷贝技术

1、java的NIO

先说java,是因为要给下面的netty做铺垫,在 Java NIO 中的通道(Channel)就相当于操作系统的内核空间(kernel space)的缓冲区,而缓冲区(Buffer)对应的相当于操作系统的用户空间(user space)中的用户缓冲区(user buffer)。

堆外内存(DirectBuffer)在使用后需要应用程序手动回收,而堆内存(HeapBuffer)的数据在 GC 时可能会被自动回收。因此,在使用 HeapBuffer 读写数据时,为了避免缓冲区数据因为 GC 而丢失,NIO 会先把 HeapBuffer 内部的数据拷贝到一个临时的 DirectBuffer 中的本地内存(native memory),这个拷贝涉及到 sun.misc.Unsafe.copyMemory() 的调用,背后的实现原理与 memcpy() 类似。 最后,将临时生成的 DirectBuffer 内部的数据的内存地址传给 I/O 调用函数,这样就避免了再去访问 Java 对象处理 I/O 读写。

(1)MappedByteBuffer

MappedByteBuffer 是 NIO 基于内存映射(mmap)这种零拷贝方式的提供的一种实现,意思是把一个文件从 position 位置开始的 size 大小的区域映射为内存映像文件。这样之添加地址映射,而不进行拷贝。

(2)DirectByteBuffer

DirectByteBuffer 的对象引用位于 Java 内存模型的堆里面,JVM 可以对 DirectByteBuffer 的对象进行内存分配和回收管理,是 MappedByteBuffer 的具体实现类。因此同样具有零拷贝技术。

(3)FileChannel

FileChannel 定义了 transferFrom() 和 transferTo() 两个抽象方法,它通过在通道和通道之间建立连接实现数据传输的。

我们直接看Linux2.4的版本,socket缓冲区做了调整,DMA带收集功能。

(1)DMA从拷贝至内核缓冲区

(2)将数据的位置和长度的信息的描述符增加至内核空间(socket缓冲区)

(3)DMA将数据从内核拷贝至协议引擎

这个复制过程是零拷贝过程。

2、Netty

Netty 中的零拷贝和上面提到的操作系统层面上的零拷贝不太一样, 我们所说的 Netty 零拷贝完全是基于(Java 层面)用户态的。

(1)Netty 通过 DefaultFileRegion 类对FileChannel 的 tranferTo() 方法进行包装,相当于是间接的通过java进行零拷贝。

(2)我们的数据传输一般都是通过TCP/IP协议实现的,在实际应用中,很有可能一条完整的消息被分割为多个数据包进行网络传输,而单个的数据包对你而言是没有意义的,只有当这些数据包组成一条完整的消息时你才能做出正确的处理,而Netty可以通过零拷贝的方式将这些数据包组合成一条完整的消息供你来使用。

此时零拷贝的作用范围仅在用户空间中。那Netty是如何实现的呢?为此我们就要找到Netty进行数据传输的接口,这个接口一定包含了可以实现零拷贝的功能,这个接口就是ChannelBuffer。

既然有接口肯定就有实现类,一个最主要的实现类是CompositeChannelBuffer,这个类的主要作用是将多个ChannelBuffer组成一个虚拟的ChannelBuffer来进行操作

为什么说是虚拟的呢,因为CompositeChannelBuffer并没有将多个ChannelBuffer真正的组合起来,而只是保存了他们的引用,这样就避免了数据的拷贝,实现了Zero Copy。

(3)ByteBuf 可以通过 wrap 操作把字节数组、ByteBuf、ByteBuffer 包装成一个 ByteBuf 对象, 进而避免了拷贝操作

(4)ByteBuf 支持 slice 操作, 因此可以将 ByteBuf 分解为多个共享同一个存储区域的 ByteBuf,避免了内存的拷贝

3、kafka

Kafka 的索引文件使用的是 mmap + write 方式,数据文件使用的是 sendfile 方式。适用于系统日志消息这种高吞吐量的大块文件的数据持久化和传输。

如果有10个消费者,传统方式下,数据复制次数为4*10=40次,而使用“零拷贝技术”只需要1+10=11次,一次为从磁盘复制到页面缓存,10次表示10个消费者各自读取一次页面缓存。

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

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

相关文章

lv11 嵌入式开发 C工程与寄存器封装 10

目录 1 C语言工程介绍 1.1 工程模板介绍 1.2 启动代码分析 2 C语言实现LED实验 2.1 C语言如何实现寄存器读写 2.2 实现LED实验 2.3 练习 1 C语言工程介绍 1.1 工程模板介绍 工程目录,后续代码都会利用到这个目录 interface.c 写了一个main函数的框架 int …

基于springboot实现学生成绩管理系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现学生成绩管理系统演示 摘要 随着信息技术和网络技术的飞速发展,人类已进入全新信息化时代,传统管理技术已无法高效,便捷地管理信息。为了迎合时代需求,优化管理效率,各种各样的管理系统应运而生&am…

***Linux常用命令及解释

1、查看Linux的版本信息 1.1、uname -a 1.2、cat /etc/issue 1.3、cat /proc/version 1.4、hostnamectl 通过使用hostnamectl命令,可以查询和更改系统主机名,并且还可以查看Linux的发行版和内核版本。 2、删除文件 3、修改目录权限 4、解压文件 5、…

5 个适用于 Windows 的顶级免费数据恢复软件

对于计算机来说,最重要的是用户数据。除了您的数据之外,有关计算机的其他所有内容都是可替换的。这三个是数据丢失的最常见原因: 文件/文件夹删除丢失分区分区损坏 文件/文件夹删除 文件/文件夹删除是最常见的数据丢失类型。大多数时候&am…

基于springboot实现农机电招平台系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现农机电招平台系统演示 摘要 随着农机电招行业的不断发展,农机电招在现实生活中的使用和普及,农机电招行业成为近年内出现的一个新行业,并且能够成为大群众广为认可和接受的行为和选择。设计农机电招平台的目的就是借助计算…

visual Studio MFC 绘制单一颜色三角形、渐变颜色边框三角形、渐变填充三角形、边框渐变的正方形与填充渐变的正方形实例

MFC 绘制三角形 本文使用visual Studio MFC 平台实现绘制单一颜色三角形、渐变颜色边框三角形、渐变填充三角形、边框渐变的正方形与填充渐变的正方形. 关于基础工程的创建请参考Visual Studio 使用MFC 单文档工程绘制单一颜色直线和绘制渐变颜色的直线 文章目录 MFC 绘制三角形…

基于springboot实现私人健身与教练预约管理系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现私人健身与教练预约管理系统演示 摘要 随着信息技术和网络技术的飞速发展,人类已进入全新信息化时代,传统管理技术已无法高效,便捷地管理信息。为了迎合时代需求,优化管理效率,各种各样的管理系统应…

Leetcode—15.三数之和【中等】

2023每日刷题&#xff08;四十一&#xff09; Leetcode—15.三数之和 实现代码 class Solution { public:vector<vector<int>> threeSum(vector<int>& nums) {sort(nums.begin(), nums.end());vector<vector<int>> ans;int i, j, k;int s,…

STM32 SCF文件

文章目录 1 SCF文件2 SCT分散加载文件3 SCF文件编写 1 SCF文件 keil编译器在链接的时候&#xff0c;是根据分散加载(.scf后缀的文件)来确定程序的加载域和运行域的。 加载域就是程序运行前在flash中具体分区情况执行域就是程序运行后&#xff0c;程序在flash和ram中的分区情况…

服务运营 |精选:病人向何处去?医院调度的几种建模方法(上)

推文作者&#xff1a; Shutian Li 编者按&#xff1a; 住院流程&#xff08;Inpatient Flow&#xff09;是一种通过协调和优化医院内部流程&#xff0c;以提高患者入院至出院期间的效率和质量的方法。住院流程通常通过医院内部信息系统和协同工作流程进行管理&#xff0c;以确…

Proteus仿真--基于1602LCD的秒表设计

本文介绍基于1602LCD的秒表设计&#xff08;完整仿真源文件及代码见文末链接&#xff09; 仿真图如下 本设计中80C51单片机作为主控&#xff0c;用1602LCD作为显示模块&#xff0c;共有2个按键&#xff0c;K1按键用于秒表计时启停控制&#xff0c;K2用于清零显示内容 仿真运…

Deepin使用记录-deepin系统开启SSH服务

1、检查安装的deepin系统是否已经开启SSH功能。 $ ps -e | grep ssh $ ps -e | grep ssh 查看是否启动ssh 2、安装openssh-server服务 sudo apt-get install openssh-server 如果出现以上提示&#xff0c;就表示你已经安装了ssh服务&#xff0c;只是还没有启动。 3、安装完…

Scope 模块

Scope 模块可以连接任何类型的实数信号线 (不支持复数)。 波形显示界面主要包括两个部分: Scope 独有的工具栏、波形显示区域。 波形显示界面默认是黑色背景, 当有单个信号输入时, 信号线是黄色的。 Scope 模块也有菜单栏, 只不过默认将其句柄和显示都隐藏起来, 可以通过下面…

Kafka-TopicPartition

Kafka主题与分区 主题与分区 topic & partition&#xff0c;是Kafka两个核心的概念&#xff0c;也是Kafka的基本组织单元。 主题作为消息的归类&#xff0c;可以再细分为一个或多个分区&#xff0c;分区也可以看作对消息的二次归类。 分区的划分为kafka提供了可伸缩性、水…

RocketMq 主题(TOPIC)生产级应用

RocketMq是阿里出品&#xff08;基于MetaQ&#xff09;的开源中间件&#xff0c;已捐赠给Apache基金会并成为Apache的顶级项目。基于java语言实现&#xff0c;十万级数据吞吐量&#xff0c;ms级处理速度&#xff0c;分布式架构&#xff0c;功能强大&#xff0c;扩展性强。 官方…

Vue框架学习笔记——事件scroll和wheel的区别

文章目录 前文提要滚动条滚动事件 scroll鼠标滚动事件 wheel二者不同点 前文提要 本人仅做个人学习记录&#xff0c;如有错误&#xff0c;请多包涵 滚动条滚动事件 scroll scroll事件绑定html页面中的指定滚动条&#xff0c;无论你拖拽滚动条&#xff0c;选中滚动条之后按键盘…

学生信息管理系统程序Python

系统主界面 在该界面中可以选择要使用功能对应的菜单进行不同的操作。在选择功能菜单时&#xff0c;有两种方法&#xff0c; 一种是输入1&#xff0c;另一种是按下键盘上的↑或↓方向键进行选择。这两种方法的结果是一样的&#xff0c;所以使用哪种方法都可以。 &#xff08;…

【Docker】安装MySQL 通俗易懂 亲测没有任何问题

目录 1.拉取镜像 2.运行容器 3.创建mysql配置文件 4.测试 1.拉取镜像 dockerhub官网&#xff1a;Docker 如果需要其他版本mysql docker pull mysql:xxx&#xff08;版本&#xff09; docker pull mysql #默认拉取最新版本 latest 2.运行容器 docker run -d -p 3306:33…

《大江大河2》最触动我的两段经典对话

第一部分 默默的关注了《大江大河》&#xff0c;第2部依旧保持了和第1部的水准&#xff0c;难得看到这么良心的电视剧。 相比于原剧本来说&#xff0c;我更喜欢改编后的内容&#xff0c;剧情更加凝重&#xff0c;深刻&#xff0c;关键是真实。 宋运辉开始是不认识路司长的&…

前端web开发学习笔记

JavaWeb 前端Web开发HTMLCSSjavaScript1.JS引入2.JS基础语法3.JS函数4.JS对象 BOMDOM文档对象模型JS事件监听VueVue常用指令Vue的生命周期 AjaxAxios 前端工程化环境准备NodeJS安装和Vue-cli安装vue项目Vue组件库Element组件的使用 Vue路由Nginx打包部署 前端Web开发 HTML 负…