零拷贝实现流程梳理

2019-08-23  本文已影响0人  死鱼

何为零拷贝?

我们先从linux正常的数据读写场景入手:

数据读写图解
当用户需要把信息从一个物理入口传送到另一个物理出口的时候,需要经历这些操作:
1、通过DMA把数据传送到内核内存中
2、cpu把数据复制到用户内存中
3、cpu把数据复制到缓冲区中
4、通过DMA把数据传送到网卡中
零拷贝的作用就是减少两次无谓的CPU复制

零拷贝如何实现

第一步:消灭第一个CPU复制

使用 mmap() 函数替代 read() 来读取数据;

buffer = mmap(inputFd, length);

应用程序调用mmap后,数据会通过DMA的方式读取到内核内存区中。然后,linux会把这段内核内存和用户内存共享。这样就能节省了第一个CPU复制。

mmap读写流程
第二步:消灭第二个CPU复制

这里就要用到系统调用 sendfile() 函数


sendfile流程

sendfile函数做的事情就是调用mmap(),把数据写到共享内存后,再把数据拷贝到socket缓冲区里去。

而这个过程是可以优化的。这里默认使用方式是cpu把数据从页缓存复制到socket缓冲区中,但其实是可以把入口数据的文件描述符和数据长度传给socket缓冲区,这样DMA就能直接把数据内存数据读到网卡去了。


零拷贝流程

这一步是不会把数据复制到socket缓冲区去的,DMA引擎会直接把数据读取到网卡,这样就能节省了第二次的复制工作。

上一篇下一篇

猜你喜欢

热点阅读