IO与零拷贝

IO与零拷贝

零拷贝基本介绍
  • 零拷贝时网络编程的一个关键优化点
  • 在Java程序中,常用的零拷贝又mmap(内存映射)和sendFile。那么在OS中的设计时如何,我们需分析mmap和sendFile对比
  • 最后通过案例分析
用户进程与操作系统关系
  • 我们先看一张图解释“用户进程和操作系统的关系”
    请添加图片描述
  • 如上计算机系统运行时候的简化说明,在操作系统中,有用户空间,内核空间,
    • 运行在操作系统傻姑娘的进程大多是用户进程,运行在用户空间,在资源管理器里面可以看得到
    • 吧操作系统运行的空间成为系统空间
  • 为何划分用户进程和系统进程,我们需要先解释内核态(Kernel mode)和用户态(user mode),内核态可以访问系统资源,比如:
    • 处理器CPU
    • 输入输出IO,包括硬盘,内存,终端等
    • 进程管理
    • 内存
    • 设备:键盘鼠标啥的
  • 以上资源都是用户进程无法直接访问。只能通过操作系统去访问,所以也罢操作系统提供的这些功能称为“系统调用”,我们文件读写,和终端控制都是通过内核进行的。
用户进程缓冲区
  • 按照以上的设计,用户进程访问系统资源需要切换到内核态,这对于的一下特殊的内存环境,必须在系统调用之前建立好,而在系统调用结束后,CPU会从内核模式切换到用户模式,而且对照又必须回复成用户进程的上下文,这种切换就会有大量的耗时。
  • 因此我们在程序读取文件的时候,会先申请一块内存,成为buffer,每次调用read读取指定字节长度的数据,写入buffer。之后的程序都从buffer中获取数据。当buffer用完后,在进行下一次调用,填充buffer。
  • 所以说,用户缓冲区目的时为了减少系统调用次数,从而减低操作系统在用户态和核心态切换的时间。如下图对比请添加图片描述

请添加图片描述

内核缓冲区
  • 内核也有自己的缓冲区
  • 当用户进程要从磁盘读数据,内核一般步直接读磁盘,而是将CIO缓冲区中数据复制到进程缓冲区
  • 单如果内核缓冲区中没用数据,内核会吧对数据块的请求加入到请求队列,然后吧进程挂起,为其他进程提供服务。
  • 等数据一句读取到内核缓冲区时候,内核缓冲区中数据读取到用户进程,才会通知进程。
  • 此处read是吧数据从高内核缓冲区复制到进程缓冲区。write是吧进程缓冲区复制到内核缓冲区。
  • 因此内核缓冲区是为了在OS级别,提高磁盘IO的效率,优化磁盘读写操作。
    请添加图片描述
传统IO模型内存拷贝请添加图片描述
  • 流程如下:

    • DMA拷贝,从磁盘到内核,direct memory access 直接内存拷贝 不使用CPU
    • CPU将内核buffer 中的数据拷贝到 用户buffer
    • 接着通过socket传递,还是user buffer 拷贝到内核中的socket buffer
    • 最后从内核socket buffer 到引擎,就是对应的协议比如TCP/IP
  • 如上流传中

    • 状态切换3 次
    • 拷贝4次
mmap优化

请添加图片描述

  • mmap优化通过内存映射的方式,将文件映射到内核缓冲区,同时用户空间可以贡献内核空间的数据,这样,在进行网络传输的时候,减少了内核空间到用户空间的拷贝
  • mmap的优化中
    • 状态切换3次
    • 数据拷贝3次 比传统IO的形式少了一次拷贝
sendFile 优化

请添加图片描述

  • Linux 2.1版本提供了sendFile函数,基本原理如上图,数据根本不进过用户态,直接从高内核缓冲区到SocketBuffer,同时由于和用户态没关系,减少了一次上下文切换
  • sendFile的优化中
    • 上下文切换2次 比mmap还少了一次上下文切换
    • 数据拷贝3 次 与mmap一样
Linux 2.4 的sendFile

请添加图片描述

  • linux 在2.4 版本中,做了一些修改,避免了从内核缓冲区拷贝到Socketbuffer的操作,直接拷贝到协议栈,从而再次减少了一次数据拷贝
  • 入上图中,其实只有一次CPU拷贝, kernel buffer —> socket buffer ,但是拷贝的信息不多,比如length,offset 等消耗低可以忽略
  • 优化后的sendFile
    • 上下文切换2次
    • 数据拷贝 2 次比2.1版本的sendFile 还少一次拷贝
零拷贝的理解
  • 零拷贝从操作系统角度看是没用CPU拷贝,而不是一次拷贝都没有,可见在以上几个IO优化中mmap, 2.1版本的sendFile, 2.4版本的sendFile中,只有2.4版本的sendFile实现正在意义上的零拷贝
  • 从操作系统角度看,内核缓冲区之间没有数据是重复的(只有kernel buffer 一份数据),以上kernel buffer 到 socket buffer的复制都是在内核中,他们是共享的一块内存,只是同步数据的数据同步了一个offset和length
  • 零拷贝不仅带来更少的数据复制,还带来了其他性能的优势,例如更少的上下文切换,更少的CPU缓存伪共享以及无CPU校验和计算
mmap和 sendFile的区别
  • mmap 适合小数据量的读写, sendFile适合大文件的传输
  • mmap需要3次上下文切换,3次拷贝,sendFile需要 2次上下文切换,2次拷贝
  • sendFile 可以利用DMA的方式减少CPU的拷贝,mmap不能,他必须从内核拷贝到Socket buffer
NIO零拷贝的DEMO
*** @author liaojiamin* @Date:Created in 18:36 2022/8/16*/
public class NIOFileChannelTransferFormZeroCopy {private static final String filePath = "E:\\learn\\问题汇总\\MYSQL.md";private static final String filePathResult = "E:\\learn\\问题汇总\\MYSQL_1.md";public static void main(String[] args) throws IOException {FileInputStream fileInputStream = new FileInputStream(filePath);FileOutputStream fileOutputStream = new FileOutputStream(filePathResult);FileChannel inputFileChannel = fileInputStream.getChannel();FileChannel outputFileChannel = fileOutputStream.getChannel();//从目标通道中复制数据到当前通道
//        outputFileChannel.transferFrom(inputFileChannel, 0, inputFileChannel.size());//把数据从当前通道复制给目标通道inputFileChannel.transferTo(0, inputFileChannel.size(), outputFileChannel);inputFileChannel.close();outputFileChannel.close();fileInputStream.close();fileOutputStream.close();}
}
  • 使用NIO零拷贝的传递方式transferTo或者transferFrom

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

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

相关文章

从堆里找回“丢失”的代码

前言 前一阵子,使用小乌龟(TortoiseGit)提交代码的时候,错误的 Revert 了部分代码,本文记录了找回这部分代码的过程。文章标题致敬张银奎老师《格蠹汇编》的第一章 —— 从堆里抢救丢失的博客。说明: 本文的…

[Java基础]线程基础与实现多线程

代码如下&#xff1a; package MyThreadPack;public class MyThread extends Thread {Overridepublic void run() {for (int i 0;i<100;i){System.out.println(i);}} }package MyThreadPack;public class MyThreadDemo01 {public static void main(String[] args){MyThrea…

gpio 树莓派3a+_树莓派4上市:性能飙升起售价依然是35美元

旨在通过超实惠方式&#xff0c;鼓励孩子们投身编程事业的奇趣开发套件树莓派&#xff0c;在昨天迎来了Raspberry Pi 4正式开售的消息。新一代树莓派引入64位处理器、802.11ac双频Wi-Fi以及通过HAT的以太网供电(PoE)等新卖点。树莓派Raspberry Pi 4的处理能力是前一代的三倍、多…

入门级微单反性能对比

入门级相机筛选 先说挑选规则 由于微单体型小于单反&#xff0c;所以在机型选择上微单&#xff1e;单反&#xff1b;最好具备翻转屏和触摸屏&#xff1b;机身防抖不是刚需&#xff0c;但能解决小范围抖动情况下稳定问题&#xff1b;自动对焦很重要&#xff0c;眼控对焦是加分…

知识更新越来越快,但是学习起来越来越困

大家好&#xff0c;我是Z哥&#xff0c;先祝大家节日快乐。不知道这个假期你打算出门吗&#xff1f;Z哥我是打算不出远门了&#xff0c;怕死&#xff0c;哈哈。索性好好宅家里学习&#xff0c;强化一下自己。相信大家也感受到了&#xff0c;随着互联网加速了信息的流动速度&…

什么标准规定了aes加密_Python 爬虫进阶必备 | 关于某租房网站数据加密的分析(送两本 Python 书)...

关于某租房网站数据加密的分析aHR0cHM6Ly93d3cubWFvbWFvenUuY29tLw抓包分析先看看这个网站的首页数据可以看到首页的 html 是压缩的&#xff0c;但是格式化之后没有看到需要的首页数据。过滤 xhr 请求看到一个 index.json的请求可以看到这个请求的请求参数以及返回值都是密文返…

[Java基础]线程同步之卖票案列分析

案列: 卖票。 需求: 某电影院目前正在上映国产大片&#xff0c;共有100张票&#xff0c;而它有3个窗口卖票&#xff0c;请设计一个程序模拟该电影院卖票。 代码如下: package SellTicketPack;public class SellTicket implements Runnable{private int tickets 100;Overrid…

sap 标准委外和工序委外_SAP FICO零基础学习_0035_标准成本估算-主数据-物料主数据...

前辈的第35堂课&#xff1a;谢谢大家的喜欢和关注噢~这里的“前辈”其实指的是给我讲课的前辈啦&#xff0c;我不是前辈噢&#xff0c;我只是一个刚刚接触FICO的小白&#xff0c;跟大家分享前辈给我讲的东西。因为刚接触&#xff0c;学习的内容比较简单~有基础的小伙伴可以去看…

[Java基础]线程安全的类

package ThreadDemoPack01;import java.util.*;public class ThreadDemo01 {public static void main(String[] args){StringBuffer sb new StringBuffer();//线程安全StringBuilder sb2 new StringBuilder();//线程不安全Vector<String> v new Vector<String>(…

数据结构与算法-- 八皇后问题(多种实现方案)

八皇后问题解法一(排列筛选法) 本篇我们承接上一篇中的思想&#xff0c;想到了一个经典的算法题&#xff0c;八皇后问题&#xff1a;题目&#xff1a;在8*8的国际象棋上摆放8个皇后&#xff0c;使得其互相不能攻击&#xff0c;即任意两个换后不能在同一行&#xff0c;同一列&a…

Blazor WebAssembly 3.2.0 正式起飞,blazor 适合你吗?

最近blazor更新很快&#xff0c;今天在官方博客上发布了Blazor WebAssembly 3.2.0 RC&#xff1a;https://devblogs.microsoft.com/aspnet/blazor-webassembly-3-2-0-release-candidate-now-available/ &#xff0c;这是最后一次预览版了&#xff0c;功能开发都已经完成。5.19的…

中获取文件名不要扩展名_如何批量修改文件名,3s时间够不够

?点击关注Excel表哥公众号上一篇推文我们介绍了如何批量获取同一文件夹下所有的文件名。▲点此图片回顾很多读者获取到这些文件名之后的一种工作情形就是需要批量或者有针对性地修改这些文件的名称。那么但凡是这类需要批量操作的重复工作&#xff0c;Excel擅长。还是以上篇推…

数据结构与算法--死磕二叉树

死磕二叉树 近一年都比较关注算法相关的知识&#xff0c;也刷了不少题&#xff0c;之前的文章中大多也是算法相关的文章&#xff0c;但是感觉每次遇到树相关的题型都不能应对自如&#xff0c;因此还是有必要在相关知识上下功夫&#xff0c;因此有此次总结&#xff0c;以下是所…

Jenkins 中以构建 Tag 来实现版本管理

好的工具和流程能使我们事半功倍&#xff0c;而这个过程是不断迭代和演进的。关于这一块的内容&#xff0c;之前写过几篇文章&#xff1a;在团队中使用GitLab中的Merge Request工作模式敏捷下的需求和代码分支管理不断进化的分支和需求管理现在又有了些新的变化和改进&#xff…

将字符串添加负数_Go语言实现LeetCode算法:8 字符串转整数

Go语言中文网&#xff0c;致力于每日分享编码、开源等知识&#xff0c;欢迎关注我&#xff0c;会有意想不到的收获&#xff01;看到题目&#xff0c;是不是超级简单&#xff0c;用 strconv.Atoi 就可以了&#xff1f;题目当然不是这么简单的要求。1 题目描述实现atoi函数&#…

[Java基础]生产者和消费者模式概述与案例分析

代码如下: package BoxPack01;public class Box {private int milk;private boolean state false;public synchronized void put(int milk){if (state){try {wait();} catch (InterruptedException e) {e.printStackTrace();}}this.milk milk;System.out.println("送奶…

毕业4年年薪200万是怎样的一种体验?

之前的一篇文章提到过自己毕业4年&#xff0c;年薪就超过了200万。最近有很多读者问我是怎么实现的&#xff0c;过程中有哪些经验可以分享。说实话&#xff0c;这个话题不太想写&#xff0c;毕竟有炫耀嫌疑。不过问的人多了&#xff0c;发现大家对这个话题还是很关心。另外&…

自动控制原理第二版王建辉_王建辉自动控制原理配套题库名校考研真题课后答案资料课后习题章节题库模拟试题...

王建辉《自动控制原理》配套题库【名校考研真题&#xff0b;课后习题&#xff0b;章节题库&#xff0b;模拟试题】第一部分 名校考研真题 第1章 自动控制系统的基本概念 第2章 自动控制系统的数学模型 第3章 自动控制系统的时域分析 第4章 根轨迹法 第5章 频率法 第…

FluentAspects -- 基于 Fluent API 的 Aop

FluentAspects -- 基于 Fluent API 的 AopIntro上次我们做了一个简单的 AOP 实现示例&#xff0c;但是实现起来主要是基于 Attribute 来做的&#xff0c;对于代码的侵入性太强&#xff0c;于是尝试实现基于 Fluent API 的方式来做 AOP 。抽象 InterceptorResolver原来获取方法执…