【IO】零拷贝、mmap、sendfile

前言

概念: 没有发生CPU拷贝数据,都是DMA(直接内存访问)拷贝

优势:

  • 减少内核态与用户态的切换
  • 减少数据复制次数
  • 避免CPU拷贝浪费CPU资源
  • 整个内存空间只有一份数据

一、普通IO

在这里插入图片描述

应用程序想要读取磁盘文件并进行网络发送时,会发生4次上下文切换,4次数据拷贝

  1. 用户态的应用想要读取磁盘文件,会转换到内核态,通过DMA拷贝到内核缓冲区
  2. 内核态的数据通过CPU拷贝到用户态的用户缓冲区
  3. 用户态的用户缓冲区的数据通过CPU拷贝到内核态的Socket缓冲区
  4. 内核态的Socket缓冲区通过DMA拷贝到网络引擎,网络引擎发送结束后需要返回给用户态发送结果

二、mmap

在这里插入图片描述
通过对用户缓冲区和内核缓冲区建立映射,共享一块映射数据,不需要从内核缓冲区拷贝到用户缓冲区,因此:

应用程序想要读取磁盘文件并进行网络发送时,会发生4次上下文切换,3次数据拷贝

三、sendfile

1. Linux2.1的sendfile

在这里插入图片描述
Linux2.1时,提供了sendfile方法,数据直接从内核缓冲区CPU拷贝到Socket缓冲区,和用户态无关,因此:

应用程序想要读取磁盘文件并进行网络发送时,会发生2次上下文切换,3次数据拷贝

2. Linux2.4的sendfile

在这里插入图片描述
Linux2.4时,优化了sendfile方法,数据直接从内核缓冲区通过DMA拷贝到网络引擎,但是需要通过CPU拷贝少量位移信息,因此:
应用程序想要读取磁盘文件并进行网络发送时,会发生2次上下文切换,2次数据拷贝。没有通过CPU拷贝数据

四、总结与扩展

1. 结论

上下文切换次数数据拷贝次数
普通IO42次DMA,2次CPU
mmap42次DMA,1次CPU
Linux2.1版sendfile22次DMA,1次CPU
Linux2.4版sendfile22次DMA

Linux2.4版本的sendfile才真正意义上实现了零拷贝

2. 解释、扩展

知识点联系:
IO-NIO-Netty-【RocketMQ、Dubbo】
sendfile-kafka
mmap-RocketMQ

什么是用户态与内核态。

参考

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值