wangjie_fourth

may the force be with you

0%

零拷贝的了解与总结

什么是零拷贝

零拷贝技术是指计算机执行操作时,CPU不需要先将数据从某处内存复制到另一个特定区域,并且尽可能的让CPU少参与到复制的过程。这种技术通常用于通过网络传输文件时节省CPU周期和内存带宽。
现在常见实现方式是CPU将这种复制操作指定给DMA,由DMA来完成这个数据转移,CPU在整个过程中只需要执行几个指令即可。

为什么需要零拷贝

需要零拷贝的原因就是在传输文件的时候,为了更大的发挥计算机的性能。使用零拷贝技术相比较普通IO技术:

  • 能够使得CPU不参与复制过程,转而去执行其他任务;
  • 减少CPU上下文切换次数
  • 减少用户线程升级内核态次数

想要更加深入了解整个过程,需要明白以下几个概念。

内核空间和用户空间

在计算机启动的时候,整个虚拟内存可以分为内核空间和用户空间。

  • 内核空间:操作系统为内核软件预留的空间;用户线程是不允许直接对该空间操作,通过要先将自己升级为内核态才行;
  • 用户空间:普通应用程序使用的虚拟内存

这里要注意到,应用程序在将磁盘某个文件复制到某个端口时,应用线程是不能自己执行去拿数据的,必须要经过内核空间去执行。

Linux的IO读写方式

计算机的IO操作大概可以分为三种:

  • IO轮询
  • 中断操作
  • DMA执行

这里我们要明白IO轮询、中断操作方式,都是由CPU来完成数据复制过程;而且因为IO操作远慢于CPU操作,所以CPU最少要执行4次上下文切换操作。如果这台计算机频繁的执行IO复制操作,那么它CPU就很难有时间去执行其他任务。
而使用DMA的话,其数据复制过程是不需要CPU来操作,整个过程CPU只需要执行几个指令让DMA去干这种事。所以,这个时候CPU最多只会执行2次上下文切换操作。

传统复制vs零拷贝

1、传统复制

应用程序想要下载某个文件时,大概需要以下几步:

  • 告诉CPU把某个磁盘文件移到某个网络端口上;
  • CPU停下手里的活,让DMA把磁盘文件读取到某个内核缓冲区空间里,然后转过头又做自己的事了;
  • DMA将磁盘文件移到内核缓冲区后,告诉CPU数据准备好了;
  • CPU停下手里的活,让把这个内核缓冲区数据复制到用户程序的用户空间内;
  • 然后,应用程序告诉CPU把自己空间的数据复制内核缓冲区里,有一个端口会读取这个数据的;
  • CPU停下手里的活,把应用程序的数据复制到内核缓冲区里,然后告诉DMA去把这个数据移到某个网络端口上;
  • DMA把内核缓冲区数据复制到网络端口后,告诉CPU活已经干完了;
  • CPU停下手里的活,告诉应用程序刚才的活已经干完了;

2、零拷贝
零拷贝的实现方式就很多了,但有一点就是这些数据不会再复制到应用程序空间里,有些特别情况下,整个复制操作可能减少到2次就能完成上述操作。

Linux相关指令

太多了,下面链接有介绍。但还是有一个图需要介绍一下的:

其他技术实现零拷贝的方式

Java的NIO

Netty

Kafka

RocketMQ


https://zh.wikipedia.org/wiki/%E9%9B%B6%E5%A4%8D%E5%88%B6
https://zhuanlan.zhihu.com/p/83398714
https://zhuanlan.zhihu.com/p/308054212
https://github.com/wangjie-fourth/ebook/blob/main/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86-%E5%94%90%E6%9C%94%E9%A3%9E-%E7%AC%AC2%E7%89%88.pdf