详细讲解零拷贝机制的进化过程

一、传统拷贝方式

(一)操作系统经过4次拷贝

  • CPU 负责将数据从磁盘搬运到内核空间的 Page Cache 中;

  • CPU 负责将数据从内核空间的 Page Cache 搬运到用户空间的缓冲区;

  • CPU 负责将数据从用户空间的缓冲区搬运到内核空间的 Socket 缓冲区中;

  • CPU 负责将数据从内核空间的 Socket 缓冲区搬运到的网络中;

(二)4 次上下文切换

  1. read 系统调用时:用户态切换到内核态;

  1. read 系统调用完毕:内核态切换回用户态;

  1. write 系统调用时:用户态切换到内核态;

  1. write 系统调用完毕:内核态切换回用户态;

二、DMA参与下的数据拷贝

DMA参与后只是在”拷贝1“的位置,暂时交给DMA来控制,可以暂时释放CPU去做别的事情。

三、mmap+write方式实现的零拷贝

(一)上下文状态切换:

1.用户进程通过mmap方法,向操作系统内核发起IO调用,用户态切换内核态;

2.内核态切换回用户态,mmap方法返回;

3.用户进程通过write方法向操作系统内核发起IO调用,上下文从用户态切换为内核态;

4.数据从socket缓冲区拷贝到网卡结束后,上下文从内核态切换回用户态,write调用返回。

(二)数据拷贝

1. CPU利用DMA控制器,把数据从硬盘中拷贝到内核缓冲区;

2.CPU将内核缓冲区的数据拷贝到socket缓冲区

3.CPU利用DMA控制器,把数据从socket缓冲区拷贝到网卡

mmap+write方式的实现的零拷贝,IO发生了4次用户空间和内核空间的上下文切换,这个并没有节省,但是数据拷贝减少了一次。

其中2次DMA拷贝和1次CPU拷贝。

(mmap是将读缓冲区的地址和用户缓冲区的地址进行映射,内核缓冲区和应用缓冲区共享,所以节省了一次CPU拷贝,并且用户京城内存是虚拟的在,只是映射到内核读缓冲区,可以节省一半的内存空间。)

四、sendfile实现的零拷贝

sendfile是Linux2.1内核版本后引入的一个系统调用函数,

API如下:

ssize_t sendfile(int out_fd,int in_fd,off_t *offset,size_t count)
out_fd为待写入内容的文件描述符,一个socket描述符;
in_fd为待读出内容的文件描述符,必须是真实的文件,不能是socket和管道;
offset:制定从读入文件的哪个位置开始读,如果为NULL,表示文件的默认起始位置;
count 制定在fdout 和 fdin之间传输的字节数。

sendfile表示两个文件描述符之间传输数据,它是在操作系统内核中操作的,避免了数据从内核缓冲区和用户缓冲区之间的拷贝操作,因此可使用他来实现零拷贝。

(一)上下文状态切换+数据拷贝

1.用户进程发起sendfile系统调用,上下文从用户态转向内核态

2.DMA控制器,把数据从硬盘中拷贝到内核缓冲区;

3.CPU将读缓冲区中的数据拷贝到socket缓冲区;

4.DMA控制器,异步将数据从socket缓冲区拷贝到网卡;

5.上下文从内核态切换回用户态,sendfile返回。

sendfile实现的零拷贝,IO发生了两次用户空间与内核空间的上下文切换,以及3次数据拷贝,其中3次数据拷贝中,包括了2次DMA拷贝和1次CPU拷贝。那能不能把CPU的拷贝次数减少到0次呢?有的,即带有DMA手机拷贝功能的sendfile

五、sendfile+DMA scatter/gather实现的零拷贝

Linux2.4之后,对sendfile做了优化升级,引入SG-DMA技术,其实就是对DMA拷贝加入了scatter/gather操作,它可以直接从内核空间缓冲区中将数据读取到网卡。使用这个特点做零拷贝,还可以少一次CPU拷贝。

(一)上下文状态切换+数据拷贝

1.用户进程发起sendfile系统调用,上下文从用户态切换为内核态;

2.DMA控制器,把数据从硬盘中拷贝到内核缓冲区;

3.CPU把内核换乘功能区重点 文件描述信息(内核缓冲区的内存地址和偏移量)发送到socket缓冲区

4.DMA控制器根据文件描述信息,直接把数据从内核缓冲区拷贝到网卡

5.上下文从内核态奇幻回用户态,sendfile调用返回。

可以发现,sendfile+DMA scatter/gather实现的零拷贝,IO发生了2次用户空间与内核空间的上下文切换,以及2次数据拷贝。其中2次数据拷贝都是DMA拷贝,这就是真正的零拷贝技术,全程都没有通过CPU来搬运数据,所有的数据都是通过DMA来传输的。

参考:https://heapdump.cn/article/3290793

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值