零拷贝的方式以及理解

零拷贝的方式以及理解

  • DMA
  • mmap
  • sendfile
  • sendfile + DMA scatter / Gather
  • direct I/O

上一篇: 什么是零拷贝

DMA

正常的IO流程中,不管是物理设备之间的数据拷贝(比如:磁盘到内存),还是内存之间的数据拷贝(比如:用户态到内核态),都是需要CPU参与的。

看图:
在这里插入图片描述
如果是比较大的文件,这样没有任何意义的copy显然会极大的浪费CPU的效率,所以就诞生了DMA。

DMA的全称是Direct Memory Access , 顾名思义,DMA的作用就是之间将IO设备的数据拷贝到内核缓冲区中。

使用DMA的好处就是IO设备到内核之间的数据拷贝不需要CPU的参与,CPU只需要给DMA发送copy指令即可,提高了处理器的利用率。

看图:

在这里插入图片描述

mmap

正常的 read + write ,都会经历至少四次的数据拷贝,其中就包括内核态到用户态的copy,它的作用是为了安全和缓存。如果我们保证安全性,是否就让用户态和内核态共享一个缓冲区呢?这就是mmap的作用。

mmap , 全称是memory map , 翻译过来就是内存映射,顾名思义,就是将内核态和用户态的内存映射到一起。避免来回copy,实现这样的映射关系以后,进程就可以采用指针的方式读写操作这一段内存,而这个时间系统会自动会写脏页面到对应的文件磁盘上,即完成了对文件的操作而不必调用 read 、 write 等系统调用函数。相反,内核空间对这段区域的修改也之间反映到用户空间,从而可以实现不同进程间的文件共享。其函数签名如下:

void *mmap(void *addr,size_t length,int port,int flags, int fd, off_t_offset);

一般来讲,mmap会替代read方法,模型我已画出来:
在这里插入图片描述
如果这个时候系统进行IO的话,采用mmap + write 的方式,内存拷贝的次数会编程三次,上下文切换则依然是4次。

需要注意的是,mmap采用基于缺页异常的懒加载模式。通过mmap申请1000G内存的话可能仅仅只占用100Mb的虚拟内存空间,甚至没有分配实际的物理内存空间,只有当真正访问的时候,才会通过缺失页中断 的方式分配内存,但mmap不是银弹,有以下原因:

1.mmap使用时必须实现指定好内存映射的大小,因此mmap并不适合变长文件;

2.因为mmap在文件更新后会通过OS自动将脏页面回写到disk中,所以在随机写很多的情况下,mmap方式在效率上不一定会比带缓冲区的一般写快;

3.因为mmap必须要在内存中找到一块连续的地址块,如果在32-bits 的操作系统上的话,虚拟内存总大小也就2Gb左右(32位操作系统的地址空间最大为4Gb,除去1Gb系统,用户能使用的内存最多为3Gb左右(windows内核比较大,一般用户只剩下2Gb可用)。),此时就很难对4Gb大小的文件完全进行mmap,所以对于超大文件来讲,mmap并不适合。

sendfile

如果只是传输数据,并不对数据进行任何处理,譬如将服务器存储的静态文件(html、js)发送客户端用于浏览器渲染,在这种场景下,如果依然进行这么多数据拷贝和上下文切换,简直就是丧心病狂的有木有!!!所以我们就可以通过sendfile的方式,只做文件传输,而不通过用户态进行干预。

看图:在这里插入图片描述

此时我们发现,数据拷贝变成了3次,上下文切换减少到2次。
虽然这个时候已经优化了不少,但是我们还有一个问题,为什么内核要拷贝两次呢???why???(page cache -> scket cache),能不能省略这个步骤呢?答案是当然可以啦!

sendfile + DMA scatter / Gather

DMA gather 是Linux2.4引入的功能,他可以读page cache 中的数据描述信息(内存地址和偏移量)记录到 scket cache 中,由DMA根据这些将数据从读缓存区copy到网卡,相比之前减少了一次CPU拷贝的过程。
看图:
在这里插入图片描述

direct I/O

之前的mmap可以让用户态和内核态共用一个内存空间来减少拷贝,其实还有一种方式,就是硬件数据不经过内核态的空间,直接到用户态的内存中,这种方式就是 Direct I/O。换句话说, Direct I/O不会经过内核态,而是用户态和设备的直接交互,用户态的写入就是直接写入到磁盘,不会再经过操作系统刷盘处理。

这样确实拷贝次数减少,读取速度会变快,但是因为操作系统不再负责缓存之类的管理,这就必须交由程序自己去做,譬如,MySQL就是自己通过 Direct I/O完成的,同时Mysql也有一套自己的缓存系统。

同时,虽然 Direct I/O可以直接将文件写入到磁盘,但是文件相关的元信息还是要通过fsync缓存到内核空间中。

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

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

相关文章

rv1126-rv1109-以太网功能-eth-(调试篇)

先参考:以太网常见问题处理方法排查手册.pdf 调试指令: 1.首先dts修改 参考:Rockchip_Developer_Guide_Linux_GMAC_Mode_Configuration_CN.pdf 2.芯片地址尝试匹配 0~3地址都试下 &mdio { phy: phy0 { compatible "ethernet-phy-ieee802.3-c22"; reg <0…

C++之STL算法(1)

STL容器算法主要由、、组成&#xff1b;   algorithm主要有遍历、比较、交换、查找、拷贝、修改等&#xff1b; 1.遍历容器for_each for_each()函数用于完成容器遍历&#xff0c;函数参数如下&#xff1a; for_each(_InIt _First, _InIt _Last, _Fn _Func) 形参&#xff1a…

中伟视界:煤矿行业借力人工智能,防控灾害风险迈出新步伐 《“十四五”矿山安全生产规划》(应急(2022)64号),煤矿重大灾害风险防控系统

随着煤矿行业的发展&#xff0c;煤矿重大灾害风险防控成为了行业关注的重点之一。为了更好地预防和应对灾害风险&#xff0c;煤矿行业开始引入人工智能分析算法和检测场景&#xff0c;以提高灾害风险的识别和预警能力。 在煤矿的重大灾害风险防控中&#xff0c;AI算法发挥着重要…

MachMap:End-to-End Vectorized Solution for Compact HD-Map Construction

参考代码&#xff1a;None 动机与出发点 地平线的MapTR展现出了构建高精地图的能力&#xff0c;但是它的机制确实是有点复杂了。为了兼容不同车道线的朝向&#xff0c;环形车道线的起终点等情况&#xff0c;针对性设计了permute-equal的匹配逻辑&#xff0c;这样的逻辑真的是太…

VMWARE虚拟机无法正常复制粘贴

解决办法&#xff1a; 只要你拿25块钱给我&#xff0c;我立刻协助你完成这个任务&#xff0c;而且帮助你做到可以复制粘贴文件哈哈哈&#xff0c;搞不好不要钱&#xff0c;微信付款 我仔细看了&#xff0c;全网没有一个全面的解决方法&#xff0c;我这个是最全面的

以csv为源 flink 创建paimon 临时表相关 join 操作

目录 概述配置关键配置测试启动 kyuubi执行配置中的命令 bug解决bug01bug02 结束 概述 目标&#xff1a;生产中有需要外部源数据做paimon的数据源&#xff0c;生成临时表&#xff0c;以使用与现有正式表做相关统计及 join 操作。 环境&#xff1a;各组件版本如下 kyuubi 1.8…

【Kubernetes】存储类StorageClass

存储类StorageClass 一、StorageClass介绍二、安装nfs provisioner&#xff0c;用于配合存储类动态生成pv2.1、创建运行nfs-provisioner需要的sa账号2.2、对sa授权2.3、安装nfs-provisioner程序 三、创建storageclass&#xff0c;动态供给pv四、创建pvc&#xff0c;通过storage…

智能优化算法应用:基于阴阳对算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于阴阳对算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于阴阳对算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.阴阳对算法4.实验参数设定5.算法结果6.参考文…

近期Chrome浏览器 不知哪个版本升级后原先http强制跳转到https,导致服务端302强制跳转到http也没反应

关于Chrome更新http强制跳转到https解决方法 近期Chrome浏览器 不知哪个版本升级后原先http强制跳转到https&#xff0c;导致服务端302强制跳转到http也没反应一、F12检查加载的Response Headers中有没有Non-Authoritative-Reason二、找了资料后得到解决方案&#xff1a;三、找…

java之“为什么需要数据类型?基本数据类型有哪些?数据类型的应用?”

java之“为什么需要数据类型&#xff1f;基本数据类型有哪些&#xff1f;数据类型的应用&#xff1f;” 一、eclipse操作示例1、完整代码2、运行效果 一、eclipse操作示例 1、完整代码 本文通过利用代码和注解的结合来回答“在java中为什么需要数据类型&#xff1f;基本数据类…

产品入门第一讲:Axure的安装以及基本使用

&#x1f4da;&#x1f4da; &#x1f3c5;我是默&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; ​​​ &#x1f31f;在这里&#xff0c;我要推荐给大家我的专栏《Axure》。&#x1f3af;&#x1f3af; &#x1f680;无论你是编程小白&#xff0c;还是有…

二叉树的创建、销毁、层序遍历与层序遍历的进阶

二叉树的创建 #include <stdio.h> #include <assert.h> #include <stdlib.h> typedef int BTDataType;typedef struct BinaryTreeNode {BTDataType data;struct BinaryTreeNode* left;struct BinaryTreeNode* right; }TreeNode;TreeNode* BuyTreeNode(int x…