<返回更多

如何深入理解零拷贝技术

2022-09-14  网易号  互联共商
加入收藏

零拷贝技术是一种思想,指的是计算机操作时,CPU不需要先将数据从某处内存复制从某处内存复制到另一个特定区域。可见,零拷贝的特点是 CPU 不全程负责内存中的数据写入其他组件,CPU 仅仅起到管理的作用。但注意,零拷贝不是不进行拷贝,而是 CPU 不再全程负责数据拷贝时的搬运工作。如果数据本身不在内存中,那么必须先通过某种方式拷贝到内存中(这个过程 CPU 可以不参与),因为数据只有在内存中,才能被转移,才能被 CPU 直接读取计算。

零拷贝技术的具体实现方式有很多,例如:

 

 

不同的零拷贝技术应用于不同场景,下面依次进行sendfile、mmap的分析

mmap(内存映射) + write

在前面我们知道,read() 系统调用的过程中,CPU会把内核缓冲区的数据拷贝到用户的缓冲区里,于是为了减少这一步开销,我们可以用 mmap() 替换 read() 系统调用函数,mmap的系统调用作用是将内核空间地址映射为用户空间地址映射,这样CPU就不用将数据从内核态拷贝到用户态了

mmap内存映射+write

图中涉及3次数据拷贝(1次CPU拷贝、两次DMA拷贝),具体拷贝过程如下:

1、应用进程调用mmap后,DMA会把磁盘数据拷贝到内核page cache中,然后操作系统的应用进程和内核空间的共享这个缓冲区

2、应用进程再调用 write,操作系统直接将用户缓冲区的数据拷贝到 内核的socket 缓冲区中,这一切都发生在内核态,由 CPU 来搬运数据

3、最后,把内核的 socket 缓冲区里的数据,拷贝到网卡的缓冲区里,这个过程是由 DMA 搬运的。

由此可见mmap的优势:

1、可以减少一次数据拷贝的过程。

2、但这还不是最理想的零拷贝,因为把用户缓冲区的数据拷贝到内核socket 缓冲区里的工作仍然需要通过CPU完成。

3、相对于传统数据传输,mmap减少了一次CPU拷贝,上下文切换依然需要四次

sendfile

sendfile主要使用到了两个技术:

1、DMA技术

2、传递文件描述符代替数据拷贝

3、一次系统调用代替两次系统调用

下面依次讲解这三个技术的作用。

1.利用 DMA 技术

sendfile 依赖于 DMA 技术,将四次 CPU 全程负责的拷贝与四次上下文切换减少到两次,如下图所示:

sendfile利用DMA技术

DMA 负责磁盘到内核空间中的 Page cache(read buffer)的数据拷贝以及从内核空间中的 socket buffer 到网卡的数据拷贝。

2.传递文件描述符代替数据拷贝

传递文件描述可以代替数据拷贝,这是由于两个原因:

 

 

sendfile利用传递描述符

利用传递文件描述符代替内核中的数据拷贝

sendfile + SG-DMA技术传输文件,需要进行2次用户态和内核态的切换,2次数据拷贝(1次DMA拷贝,1次SG-DMA拷贝)

注意事项:只有网卡支持 SG-DMA(The Scatter-Gather Direct Memory Access)技术才可以通过传递文件描述符的方式避免内核空间内的一次 CPU 拷贝。这意味着此优化取决于 linux 系统的物理网卡是否支持,这也就意味着硬件也要受限制(Linux 在内核 2.4 版本里引入了 DMA 的 scatter/gather – 分散/收集功能,只要确保 Linux 版本高于 2.4 即可)。

3.一次系统调用代替两次系统调用

由于 sendfile 仅仅对应一次系统调用,而传统文件操作则需要使用 read 以及 write 两个系统调用。

正因为如此,sendfile 能够将用户态与内核态之间的上下文切换从 4 次讲到 2 次。

sendfile系统调用代替read/write

总结下sendfile的具体过程如下:

 

  1. 通过 DMA 将磁盘上的数据拷贝到内核缓冲区里;
  2. 缓冲区描述符和数据长度传到 socket 缓冲区,这样网卡的 SG-DMA 控制器就可以直接将内核缓存中的数据拷贝到网卡的缓冲区里,此过程不需要将数据从操作系统内核缓冲区拷贝到 socket 缓冲区中,这样就减少了一次数据拷贝;

 

此种方式对比之前的,真正意义上去除了CPU拷贝,CPU 可以去执行其他的业务计算任务,同时和 DMA 的 I/O 任务并行,极大地提升系统性能。

但他的劣势也很明显,强依赖于硬件的支持

声明:本站部分内容来自互联网,如有版权侵犯或其他问题请与我们联系,我们将立即删除或处理。
▍相关推荐
更多资讯 >>>