基础

零拷贝指的是,从一个存储区域到另一个存储区域的copy任务没有CPU参与。零拷贝通常用于网络文件传输,以减少CPU消耗和内存带宽占用,减少用户空间与CPU内核空间的拷贝过程,减少用户上下文与CPU内核上下文间的切换,提高系统效率。
用户空间指的是用户可操作的内存缓存区域,CPU内核空间是指仅CPU可操作的寄存器缓存以及内存缓存区域。
用户上下文指的是用户状态环境,CPU内核上下文指的是CPU内核状态环境。
零拷贝需要DMA控制器的协助。DMA(Direct Memory Access)直接内存存取,是CPU的组成部分,其可以在CPU内核(算术逻辑运算器ALU等)不参与运算的情况下将数据从一个地址空间拷贝到另一个地址空间。

传统拷贝方式

零拷贝(Zero Copy)
该拷贝方式共进行了4次用户空间与内核空间的上下文切换,以及4次数据拷贝,其中两次拷贝存在CPU参与。
应用程序的作用仅仅就是一个数据传输的中介,最后将kernel buffer中的数据传递到了socket buffer。显然这是没有必要的。所以就引入了零拷贝。

零拷贝

零拷贝(Zero Copy)
Linux系统(CentOS6及其以上版本)对于零拷贝是通过sendfile系统调用实现的。
该拷贝方式共进行了2次用户空间与内核空间的上下文切换,以及3次数据拷贝,但整个拷贝过程均没有CPU参与。
kernel buffer和socket buffer区别,DMA控制器所控制的拷贝过程有一个要求,数据在源头的存放地址空间必须是连续的。

Gather Copy DMA零拷贝方式

由于该拷贝方式是由DMA完成,与系统无关,所以只要保证系统支持sendfile系统调用功能即可。
零拷贝(Zero Copy)
该方式中没有数据拷贝到socket buffer。取而代之的只是将kernel buffer中的数据描述信息写到了socket buffer中。数据描述信息包含了两方面的信息:kernel buffer中数据的地址以及偏移量。
该拷贝方式进行了2次用户空间与内核空间的上下文切换,以及2次数据拷贝,并且整个拷贝过程均没有CPU的参与。
该拷贝方式的系统效率是提高了,但与传统相比,也存在不足。传统拷贝中user buffer中存有数据,因此应用程序能够对数据进行修改等操作;零拷贝中的user buffer中没有了数据,所以应用程序无法对数据进行操作了。Linux的mmap零拷贝解决了这个问题。

mmap零拷贝

零拷贝(Zero Copy)
该拷贝方式与零拷贝的唯一区别就是,应用程序与内核共享了kernel buffer。由于是共享,所以应用程序也就可以操作该buffer了。应用程序对于kernel buffer的操作,就会引发用户空间与内核空间的相互切换。
该拷贝方式共进行了4次用户空间与内核空间的上下文切换,以及2次数据拷贝,拷贝过程均没有CPU的参与。虽然较之前的零拷贝增加了两次上下文切换,但应用程序可以对数据进行修改了。

相关文章: