首页 > 其他分享 >零拷贝

零拷贝

时间:2023-03-03 09:35:05浏览次数:34  
标签:sendfile DMA 内核 缓冲区 拷贝 CPU

1.什么是零拷贝

零拷贝是指计算机在执行IO操作的时候, CPU不需要将数据从一个存储区复制到另一个存储区, 进而减少上下文切换以及 CPU 拷贝的时间, 这是一种IO操作优化技术

零拷贝不是没有拷贝数据, 而是减少用户态, 内核态的切换次数 和 CPU拷贝次数

2. 传统IO

3. 实现方式

3.1.mmap + write

虚拟内存把内核空间和用户空间的虚拟地址映射到同一个物理地址, 从而减少数据拷贝次数, mmap技术就是利用了虚拟内存的这个特点, 它将内核中的读缓冲区与用户空间的缓冲区进行映射, 所有的IO操作都在内核中完成

  1. 用户进程通过mmap方法向操作系统内核发起 IO 调用,上下文从用户态切换为内核态。

  2. CPU 利用DMA控制器,把数据从硬盘中拷贝到内核缓冲区。

  3. 上下文从内核态切换回用户态,mmap 方法返回。

  4. 用户进程通过write 方法向操作系统内核发起IO 调用,上下文从用户态切换为内核态。

  5. CPU 将内核缓冲区的数据拷贝到的 socket 缓冲区。

  6. CPU 利用DMA 控制器,把数据从 socket 缓冲区拷贝到网卡,上下文从内核态切换回用户态,write 调用返回。

mmap+write 实现的零拷贝,I/O 发生了4次用户空间与内核空间的上下文切 换,以及3 次数据拷贝(包括了2次DMA拷贝和1 次CPU 拷贝)。

3.2 sendfile

sendfile 表示在两个文件描述符之间传输数据,它是在操作系统内核中操作的, 避免了数据从内核缓冲区和用户缓冲区之间的拷贝操作

  1. 用户进程发起·sendfile 系统调用,上下文(切换 1)从用户态转向内核态

  2. DMA控制器,把数据从硬盘中拷贝到内核缓冲区。

  3. CPU 将读缓冲区中数据拷贝到 socket 缓冲区

  4. DMA 控制器,异步把数据从 socket 缓冲区拷贝到网卡,

  5. 上下文(切换2)从内核态切换回用户态,sendfile 调用返回。

2次上下文切换,2次DMA拷贝,一次cpu 拷贝

3.3 带DMA收集功能sendfile (sendfile+DMA Scatter/Gather)

linux 2.4版本之后,对sendfile做了优化升级,引入SG-DMA技术,其实就是对DMA拷贝加入了scatter/gather操作,它可以直接从内核空间缓冲区中将数据读取到网卡。使用这个特点搞零拷贝,即还可以多省去一次CPU拷贝

  1. 用户进程发起sendfile系统调用,上下文(切换1)从用户态转向内核态

  2. DMA控制器,把数据从硬盘中拷贝到内核缓冲区。

  3. CPU把内核缓冲区中的文件描述符信息(包括内核缓冲区的内存地址和偏移量)发送到socket缓冲区

  4. DMA控制器根据文件描述符信息,直接把数据从内核缓冲区拷贝到网卡

  5. 上下文(切换2)从内核态切换回用户态sendfile调用返回。

可以发现,sendfile+DMA scatter/gather实现的零拷贝,I/O发生了2次用户空间与内核空间的上下文切换,以及2次数据拷贝。其中2次数据拷贝都是包DMA拷贝。这就是真正的 零拷贝(Zero-copy) 技术,全程都没有通过CPU来搬运数据,所有的数据都是通过DMA来进行传输的。

4. DMA 技术说明

DMA,英文全称是Direct Memory Access,即直接内存访问。DMA本质上是一块主板上独立的芯片,允许外设设备和内存存储器之间直接进行IO数据传输,其过程不需要CPU的参与

5.应用场景

RocketMQKafka都使用到了零拷贝的技术。

对于MQ而言,无非就是生产者发送数据到MQ然后持久化到磁盘,之后消费者从MQ读取数据。

对于RocketMQ来说这两个步骤使用的是mmap+write,而Kafka则是使用mmap+write持久化数据,发送数据使用sendfile

6.java对零拷贝支持

6.1 Java NIOmmap的支持

MappedByteBuffer

6.2 Java NIOsendfile的支持

FileChanneltransferTo()/transferFrom(),底层就是sendfile() 系统调用函数

 

标签:sendfile,DMA,内核,缓冲区,拷贝,CPU
From: https://www.cnblogs.com/mayichidoufu/p/17174406.html

相关文章

  • 【CentOS】scp免密码远程拷贝
    https://www.likecs.com/show-307003828.html基于公钥和私钥的信任办法使用root用户,在192.168.0.30和192.168.0.31之间复制文件可以先删除旧文件rm/root/.ssh/......
  • 深浅拷贝理解与应用
    转载博客:https://baijiahao.baidu.com/s?id=1741494490514331505&wfr=spider&for=pc 执行结果:  总之:要想改变多层嵌套的可变类型的值,又想保证原有数据不变,用深拷......
  • Mac电脑无法拷贝东西到移动硬盘的解决办法
    前段时间想把一些文件从MacbookPro上拷贝到希捷USB外置硬盘上,但是试了好多次,从Mac复制文件到外部移动硬盘的时候,都没有粘贴选项。经过查阅资料后发现,Windows系统的经验在......
  • SAP CLIENT拷贝详细说明
    SAPCLIENT拷贝详细说明   相关的事物代码:   SCC3(集团拷贝时查看日志)   SCC4(配置全部集团的目录)   SCC5(集团删除)   SCCL(执行集团拷......
  • 浅拷贝导致的bug
    目录深拷贝与浅拷贝区别hutoolBeanUtil.copyProperties浅拷贝问题重现实现深拷贝的一些工具深拷贝与浅拷贝区别在Java中,除了基本数据类型(元类型)之外,还存在类的实例......
  • 一切皆对象和深浅拷贝
    一切皆对象图示:  深浅copy:  ......
  • 【JavaScript】27_浅拷贝和深拷贝 + 对象的复制
    7、浅拷贝和深拷贝浅拷贝(shallowcopy)通常对对象的拷贝都是浅拷贝浅拷贝顾名思义,只对对象的浅层进行复制(只复制一层)如果对象中存储的数据是原始值,那么拷贝的深浅是不重要浅......
  • 拷贝构造函数调用时机
    这里讨论两种情况下的拷贝函数调用:作为参数传值过程中的拷贝函数调用,有一个Dog类,d1是Dog类的一个实例现在通过function将d1传入,voidfunction(Dogdog);d1是dog的实参,在......
  • 深拷贝
    functiondeepClone(source){vartargetObj=Array.isArray(source)===Array?[]:{};for(varkeysinsource){i......
  • Lodash中的_.cloneDeep(value) 深拷贝和_.clone(value) 浅拷贝
    Lodash是一个一致性、模块化、高性能的JavaScript实用工具库。_.cloneDeep(value)这个方法类似_.clone,除了它会递归拷贝 value。(注:也叫深拷贝)。参数:  value (*......