零拷贝的原理及应用方式

缓存区

用户缓存区

用户缓冲区的目的是为了减少系统调用次数,从而降低操作系统在用户态与核心态切换所耗费的时间

程序在读取文件时,会先申请一块内存数组,称为buffer,然后每次调用read,读取设定字节长度的数据,写入buffer。(用较小的次数填满buffer)。之后的程序都是从buffer中获取数据,当buffer使用完后,在进行下一次调用,填充buffer。

内核缓存区

读磁盘数据时 先把数据从磁盘读到缓冲区。 然后将内核缓冲区的数据复制到进程缓冲区中。
当内额缓冲区没有数据时,内核会把对数据块的请求,加入到请求队列,然后把进程挂起,为其它进程提供服务。等io完成时 才会通知进程。
不同的io模型,在调度和使用内核缓冲区的方式上有所不同

数据拷贝过程

仅CPU

应用程序调用read(),CPU发起IO请求,磁盘控制器搬运数据。发起IO中断
CPU拷贝数据: 磁盘缓冲区-内核缓冲区-用户缓冲区

CPU&DMA方法

直接内存访问(Direct Memory Access),是一种硬件设备绕开CPU独立直接访问内存的机制。所以DMA在一定程度上解放了CPU,把之前CPU的杂活让硬件直接自己做了,提高了CPU效率。

目前支持DMA的硬件包括:网卡、声卡、显卡、磁盘控制器等。
有了DMA,CPU直接和内核缓冲区交换数据。

普通数据交互过程

读过程:
read切换到内核态
DMA读数据
CPU将数据从内核缓冲区复制到用户缓冲区
read返回切换到用户态
写过程:
write切换内核态
CPU将数据从用户缓冲区拷贝到内核缓冲区
DMA将数据拷贝到socket缓冲区
write返回切换到用户态

零拷贝

mmap方式

将内核中读缓冲区地址与用户空间缓冲区地址进行映射,从而实现内核缓冲区与用户缓冲区的共享。
CPU只需让数据从内核缓冲区拷贝到套接字缓冲区。减少了一次拷贝。

sendfile方式

sendfile方式只使用一个函数就可以完成之前的read+write 和 mmap+write的功能,这样就少了2次状态切换,由于数据不经过用户缓冲区,因此该数据无法被修改。

sendfile调用时进入内核态 DMA从disk拷贝来的数据放入内核缓冲区 然后CPU将内核缓冲区的数据拷贝到套接字缓冲区 DMA将套接字缓冲区拷贝到网卡 sendfile返回 切换到用户态。

sendfile+DMA

升级后的sendfile将内核空间缓冲区中对应的数据描述信息(文件描述符、地址偏移量等信息)记录到socket缓冲区中。

DMA控制器根据socket缓冲区中的地址和偏移量将数据从内核缓冲区拷贝到网卡中,从而省去了内核空间中仅剩1次CPU拷贝。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值