零拷贝mmap和sendfile

前言

需要了解的知识

用户态、内核态
系统调用
DMA、CPU拷贝

传统io

传统io:会经过四次内核态和用户态上下文切换,四次数据的拷贝
传统io流程
在这里插入图片描述

1、用户程序发起read()系统调用,由用户态切换为内核态(1次状态切换)
2、内核通过DMA把数据读进内核缓冲(1次DMA拷贝),再把数据通过cpu拷贝到用户缓冲(1次cpu拷贝复制),read()系统调用结束返回
	  内核态切换为用户态(1次状态切换)
3、用户调用write()系统调用,由用户态切换为内核态(1次状态切换),将数据从用户缓冲拷贝进内核缓冲(1次cpu拷贝复制)
4、内核将数据通过DMA拷贝到网卡(1次DMA拷贝),结束read()系统调用返回,由用户态切换为内核态(1次状态切换)

2次DMA拷贝、2次cpu拷贝、4次内核态用户态切换

mmap

使用mmap系统调用:会经过四次内核态和用户态上下文切换,三次数据的拷贝
在这里插入图片描述

1、用户程序发起mmap()系统调用,将用户缓冲和内核缓冲做映射,由用户态切换为内核态1次状态切换),
2、内核通过DMA将数据拷贝到内核缓冲(一次DMA拷贝),mmap()调用返回,由内核态切换为用户态(1次状态切换)
3、用户程序发起write()系统调用,由用户态切换为内核态(一次切换),因为做了映射:内核直接通过cpu拷贝数据到
   输出的缓冲区(1次cpu拷贝)
4、内核通过DMA把数据拷贝到硬件网卡(一次DMA拷贝),write()系统调用返回,由内核态切换为用户态(1次状态切换)

2次DMA拷贝、1次cpu拷贝、4次内核态用户态切换

sendfile

使用sendfile系统调用:会经过两次内核态和用户态上下文切换,三次数据的拷贝
在这里插入图片描述

1、用户程序发起sendfile()系统调用,由用户态切换为内核态1次状态切换),
2、内核通过DMA将数据拷贝到内核缓冲(一次DMA拷贝)
3、内核直接通过cpu拷贝数据到输出的缓冲区(1次cpu拷贝)
4、内核通过DMA把数据拷贝到硬件网卡(一次DMA拷贝),sendfile()系统调用返回,由内核态切换为用户态(1次状态切换)

只需要sendfile一个系统调用
2次DMA拷贝、1次cpu拷贝、2次内核态用户态切换
这其实还是会有一次cpu拷贝,如何实现真正的零拷贝?

sendfile+DMA scatter/gather实现真正的零拷贝

在这里插入图片描述

1、用户程序发起sendfile()系统调用,由用户态切换为内核态1次状态切换),
2、内核通过DMA将数据拷贝到内核缓冲(一次DMA拷贝)
3、内核把缓冲区的地址以及偏移量(数据长度)发送到到输出的缓冲区
4、内核通过DMA把数据从内核缓冲直接通过DMA拷贝到硬件网卡(一次DMA拷贝),sendfile()系统调用返回,由内核态切换为用户态(1次状态切换)

2次DMA拷贝、2次内核态用户态切换;没有cpu拷贝:真正的零拷贝

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值