零拷贝、mmap、sendfile

目录

    • 零拷贝
    • mmap
    • sendFile
    • 总结

零拷贝

要了解零拷贝,首先得先了解一下传统 IO 的执行流程,这里举个例子,通过传统的 IO 进行网络传输来传输一个文件。
在这里插入图片描述
先上一张图,这张图就代表了传统 IO 传输文件的流程。

读取文件的时候,会从用户态切换为内核态,同时基于 DMA 引擎将磁盘文件拷贝到内核缓冲区。

看到这里,可能你就已经懵逼了,什么是用户态和内核态,什么是 DMA 拷贝,我用大白话解释一下

首先用户态其实就是 CPU 在执行你的代码,而内核态呢,其实就是你没有那个权限去操作硬件,所以只能交给系统去调用,这个时候就是内核态。举个例子,你的女朋友需要你修个电脑(醒醒,但凡有一粒花生米也不至于喝成这样),我换个说法,假如你同班的女同学想让你修个电脑,但是宿管阿姨不肯放你进女生宿舍,这个时候你就是用户态,你不能进女生宿舍,所以你只能让宿管阿姨(内核态)来帮你把电脑取出来。

那什么是 DMA 拷贝呢,DMA(DirectMemoryAccess,直接内存存取)其实就是因为 CPU 老哥太累了,所以找了个小弟,就是 DMA 替他完成一部分的拷贝工作,这样 CPU 就能去做其他事情了。

讲完了内核态和用户态还有 DMA 的大概意思,我们接着回到刚才的 IO 流程中,第一步我们将文件从磁盘文件读到了用户缓冲区,此时经历了一次上下文切换和一次拷贝。

由内核态切换为用户态,基于 CPU 把内核缓冲区的数据拷贝到用户缓冲区。

调用 socket 的输出流的 write 方法的话,此时会从用户态切换到内核态,同时基于 CPU把用户缓冲区里的数据拷贝到 Socket 缓冲区里去,接着会有一个异步化的过程,基于 DMA 引擎从 Socket 缓冲区里把数据拷贝到网络协议引擎里发送出去。

当 IO 操作完成之后,又从内核态切换为用户态。

通过上面的步骤可以发现传统的 IO 操作执行,有 4 次上下文的切换和 4 次拷贝,是不是很繁琐。

零拷贝的话,一般有 mmap 和 sendFile 两种,一个一个来说。

mmap

mmap 是一种内存映射技术,mmap 相比于传统的 IO 来说,其实就是少了 1 次 CPU 拷贝而已,上图。
在这里插入图片描述
传统 IO 里面从内核缓冲区到用户缓冲区有一次 CPU 拷贝,从用户缓冲区到 Socket 缓冲区又有一次 CPU 拷贝。mmap 则一步到位,直接基于 CPU 将内核缓冲区的数据拷贝到了 Socket 缓冲区。

之所以能够减少一次拷贝,就是因为 mmap 直接将磁盘文件数据映射到内核缓冲区,这个映射的过程是基于 DMA 拷贝的,同时用户缓冲区是跟内核缓冲区共享一块映射数据的,建立共享映射之后,就不需要从内核缓冲区拷贝到用户缓冲区了。

虽然减少了一次拷贝,但是上下文切换的次数还是没变。

RocketMQ 中就是使用的 mmap 来提升磁盘文件的读写性能。

sendFile

在 Linux 中,提供 sendFile 函数,实现了零拷贝,依旧是先上图。
在这里插入图片描述
可以看到在图中,已经没有了用户缓冲区,因为用户缓冲区是在用户空间的,所以没有了用户缓冲区也就意味着不需要上下文切换了,就省略了这一步的从内核态切换为用户态。

同时也不需要基于 CPU 将内核缓冲区的数据拷贝到 Socket 缓冲区了,只需要从内核缓冲区拷贝一些 offset 和 length 到 Socket 缓冲区。

接着从内核态切换到用户态,从内核缓冲区直接把数据拷贝到网络协议引擎里去;同时从 Socket 缓冲区里拷贝一些 offset 和 length 到网络协议引擎里去,但是这个 offset 和 length 的量很少,几乎可以忽略。

sendFile 整个过程只有两次上下文切换和两次 DMA 拷贝,很重要的一点是这里完全不需要 CPU 来进行拷贝了,所以才叫做零拷贝,这里的拷贝指的就是操作系统的层面。

那你肯定会问,那 mmap 里面有一次 CPU 拷贝为啥也算零拷贝,只能说那不算是严格意义上的零拷贝,但是他确实是优化了普通 IO 的执行流程,就像老婆饼里也没有老婆嘛。

Kafka 和 Tomcat 内部使用就是 sendFile 这种零拷贝。

总结

传统 IO 执行的话需要 4 次上下文切换(用户态 -> 内核态 -> 用户态 -> 内核态 -> 用户态)和 4 次拷贝(磁盘文件 DMA 拷贝到内核缓冲区,内核缓冲区 CPU 拷贝到用户缓冲区,用户缓冲区 CPU 拷贝到 Socket 缓冲区,Socket 缓冲区 DMA 拷贝到协议引擎)。

mmap 将磁盘文件映射到内存,支持读和写,对内存的操作会反映在磁盘文件上,适合小数据量读写,需要 4 次上下文切换(用户态 -> 内核态 -> 用户态 -> 内核态 -> 用户态)和3 次拷贝(磁盘文件DMA拷贝到内核缓冲区,内核缓冲区 CPU 拷贝到 Socket 缓冲区,Socket 缓冲区 DMA 拷贝到协议引擎)。

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

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

相关文章

网页服务器和mysql服务器_实现Web服务器之间使用同一个MYSQL和相同的网页配置文件的方法...

实现Web服务器之间使用同一个MYSQL和相同的网页配置文件的方法发布时间:2020-04-15 16:42:41来源:亿速云阅读:133作者:三月栏目:数据库亿速云负载均衡(Cloud Load Balancer)是对多台云服务器进行流量分发的服务。亿速云…

传128GB版iPad4售价为799/929美元

外媒9to5mac报道,苹果将推出一款升级版iPad4,外观和iPad 4相同,还是黑白两色的,只加入了新的SKU。 据报道,这款升级版iPad4还有128GB版,随着这条消息传出,不久关于128GB版iPad4的售价信息也传出…

(西工程-金花)小米路由器连接哆点设置WiFi保姆式教程

小米路由器连接电源,用根网线一端插入寝室的网口处,另一端插入小米路由器的WAN口手机或者电脑连接WiFi,我这里是通过手机浏览器打开192.168.31.1进入无线路由器管理页面进行配置小米路由器,配置WiFi的一些基本参数,例如:WiFi名称,密码之类的信息 进入无线路由器管理…

基于MINA框架快速开发网络应用程序

1.MINA框架简介 Netty、Mina、Cindy都是不错的NIO开源框架,后两者都是在Netty的基础上演化出来的。MINA(Multipurpose Infrastructure for Network Applications)是用于开发高性能和高可用性的网络应用程序的基础框架。通过使用MINA框架可以可以省下处理…

Python中@staticmethod和@classmethod之间的区别

classmethod装饰器 (The classmethod Decorator) The classmethod decorator is an inbuilt function decorator that gets evaluated after the function is defined. The result of the evaluation shadows the function definition. The classmethods first argument is alw…

go 声明二维数组_一篇文章了解Go语言中数组Arrays的使用内幕

概述与其他编程语言类似,Go语言也有数组array。Go语言中,数组的行为和其他语言没有什么不同.Go语言中还有一个叫做切片slice的东西,它就像是对数组的引用。在本文中,我们将只研究数组。定义数组是同一类型元素的连续集合&#xff…

ffmpeg 使用ffplay 进行 hls 拉流 分析 1

ffmpeg 使用 ffplay 进行 hls 拉流 分析 1 从使用ffplay 调用 http://192.168.1.100:8080/live/livestream.m3u8 开始,进入到ffmpeg 的分析使用的协议选择相应的解复用器的步骤。 其他协议或者文件方式的使用ffplay也是这个步骤流程的。 目录:一、流程图…

搜狗输入法输出特殊符号快捷键

https://www.petefreitag.com/cheatsheets/ascii-codes/ 参考上个编码网站大全 详细步骤为:alt长按 + 编码数字 例如:平方的编码为178-----长按alt178 即可,178是数字一个一个挨个按即可 常用的特殊符号如下: 平方&…

echo 12345678 | base64 产生的结果跟12345678真正的base64编码不对

echo "12345678" | base64 产生的结果跟"12345678"真正的base64编码不对 弄了好久才搞清楚,echo 命令是带换行符的,改成echo -n "12345678" | base64就没问题了转载于:https://www.cnblogs.com/senix/archive/2013/01/30/…

[BuildRelease Management]CC.NET架构

一 CC.NET的操作流程 1) 等待Trigger的唤醒; 2)从Source Control System查询上次build以后的修改列表; 3)如果任何修改被发现或是Trigger触发类型为 force the build : 3.1)为build产生一个label number&a…

python 入门到实践期末考试常出现的考试内容_Python编程入门到实践—列表篇(一)...

一、列表是什么?列表由一系列按特定顺序排列的元素组成。可以创建包含字母表中所有字母、数字0-9或所有家庭成员姓名的列表;也可以将任何东西加入列表中,其中的元素之间可以没有任何关系。列表通常包含多个元素,给列表指定一个表示…

c#中将集合写入文本_在C#中将记录插入MySQL数据库

c#中将集合写入文本In the last tutorial (how to connect with MySQL database in C#?), we learned about making the connection with MySQL database in C#. Here, in this tutorial, we will learn how to insert the records in MySQL database in C#? 在上一教程( 如何…

read/fread write/fwrite 的区别

fread就是通过read来实现的,fread是C语言的库,而read是系统调用。 差别在read每次读的数据是调用者要求的大小,比如调用者要求读取10个字节数据,read就会从内核缓冲区(操作系统开辟的一段空间用来存储磁盘上的数据&am…

如何在子网中访问上层网络的计算机文件夹

场景 公司路由器A,直接接外部网线,内部ip192.168.11.1,lan口又接了路由器A1,IP为192.168.11.2,A1的lan端口接了一台电脑A,Ip为192.168.0.2,接了另外一个路由A2,Ip为192.168.11.3&…

基于Web的套打方案分析

应用web化,不论对开发商,还是对用户来说,实在是一种很经济的选择,因为基于web的应用,客户端的规则很简单,容易学习,容易维护,容易发布。但对程序员来说,因为浏览器的局限…

day1-Linux操作系统基础

该专栏所有内容笔记均来自传智播客培训班 1.什么是操作系统(operate system OS) 小议:承上启下作用,向下可以控制硬件,向上能够支持软件的运行。一个可以控制硬件的软件。 小明找小红聊天,小明打开QQ&…

关闭浏览器 清空session_跨境网络小知识之Session

跨境小伙伴们大家好,上一篇为大家介绍了Cookie,今天就为大家介绍下连接cookie的另一端Session,交互过程中,二者缺一不可。与Cookie相对,Session是存储在服务端的,他们之间是通过一个叫做sessionID的东东建立…

我和乘子交替方向法admm_找到最大和交替子序列

我和乘子交替方向法admmProblem statement: 问题陈述: Given a sequence of numbers, you have to find the maximum sum alternating subsequence and print the value. A sequence is an alternating sequence when it will be maintain like (increasing) ->…

Dojo学习笔记(一):Hello Dojo!

欢迎来到Dojo世界!在这篇文章中你将会学习到如何加载Dojo以及探索Dojo的一些核心功能。你还会了解Dojo的基于AMD的模块架构,探索如何加载额外的模块来增加功能到您的Web站点或应用程序,并找出在出错的时如何得到帮助。让我们开始吧 开始学习D…

转:我眼中的Visual Studio 2010架构工具

来自:http://www.cnblogs.com/wayfarer/archive/2010/07/30/1788398.html我眼中的Visual Studio 2010架构工具影响架构质量的是构建体系架构的思想、原则、实践与架构师的经验,绝不是工具。即使是最优秀的架构工具,也不可能像倚天宝剑一般——…