Netty学习之零拷贝

一、零拷贝

所谓零拷贝,即不经过CPU的拷贝方式。

1.传统IO

在传统的IO中,拷贝经过以下几个步骤:
拷贝:硬盘->(DMA)内核->(CPU)用户buffer->(CPU)socket buffer->(DMA拷贝)协议引擎

对应的切换模式如下:
切换:用户->内核->用户->内核

图解如下,上图是切换模式,下图是拷贝所需要经过的过程:
其中DMA copy即直接内存拷贝,不经过CPU
在这里插入图片描述

2.mmap——内存映射优化

为了减少CPU拷贝,后面提出了MMAP模式。

mmap通过内存映射,将文件映射到内核缓冲区,同时,用户空间可以共享内核空间的数据。

其过程如下:
拷贝:硬盘->(DMA)内核->(CPU)socket buffer->(DMA拷贝)协议引擎

切换模式如下:
切换:用户->内核->内核

在这里插入图片描述

其中,我们可以看到,mmap减少了一次cpu拷贝,从内核buffer直接拷贝到socket buffer,同样,减少了一次切换

虽然这样优化了拷贝方式,但并不是真正的零拷贝

3.sendFile函数

直到sendFile的出现,才算真正的零拷贝。

sendFile优化:
Linux2.1提供了sendFile函数,数据不用经过用户态,直接从内核缓冲区进入到SocketBuffer,减少一次切换。

拷贝:硬盘->(DMA)内核->(CPU)socket buffer->(DMA拷贝)协议引擎

切换:用户->内核->内核

在这里插入图片描述

sendFile优化:
Linux2.4提供了sendFile函数,数据不用经过用户态,直接从内核缓冲区进入到协议引擎 ,又减少一次切换,实现真正零拷贝(其实也经过了socket buffer,但是拷贝的信息很少,只有length,offset等信息,可忽略)

拷贝:硬盘->(DMA)内核->(DMA拷贝)协议引擎
切换:用户->内核->内核
在这里插入图片描述
在netty中应用:transferto函数

二、比较

mmap和sendFile的区别
1.mmap适合小数据量读写,sendFile适合大文件传输

2.mmap至少需要4次上下文切换,3次数据拷贝,sendFile需要3次上下文切换,最少2次数据拷贝

3.sendFile可以利用DMA方式,减少CPU拷贝,mmap则没有。

猜你喜欢

转载自blog.csdn.net/weixin_43896829/article/details/110502435