零拷贝的简单复习

PageCache

PageCache是内核缓冲区


DMA

没有DMA前的IO:整个数据的传输过程,都需要 CPU 亲自参与搬运数据的过程,而且这个过程中CPU 是不能做其他事情的

CPU发起IO
磁盘将数据放到磁盘缓冲区
CPU将磁盘缓冲区数据放到内核缓冲区
CPU将内核缓冲区放到用户缓冲区

DMA技术(直接内存访问):CPU 不再参与「将数据从磁盘控制器缓冲区搬运到内核空间」的工作,这部分工作全程由 DMA 完成

CPU发起IO
磁盘将数据放到磁盘缓冲区
DMA将磁盘缓冲区数据放到内核缓冲区
DMA将内核缓冲区放到用户缓冲区

有DMA的时候,CPU全盘负责磁盘IO

有了DMA后,DMA分担了IO中磁盘文件拷贝到磁盘缓冲区和磁盘缓冲区拷贝到内核缓冲区的工作


传统文件传输

四次拷贝:流程:磁盘文件->内核缓冲区->用户缓冲区->Socket缓存区->网卡

四次用户态和内核态的上下文切换:

read():用户态变成内核态,结束后内核态变回用户态

write():用户态变成内核态,结束后内核态变回用户态


优化文件传输的性能

  1. 减少系统调用次数,一次系统调用必然会发生 2 次上下文切换,因为上下文开销大,所以我们要尽量减少系统调用read(),write()
  2. 数据实际上不需要搬到用户空间,因为在用户空间我们并不会对数据「再加工」,因此用户的缓冲区是没有必要存在的

零拷贝

传统文件拷贝流程:

        DMA拷贝           CPU拷贝            CPU拷贝              DMA拷贝
磁盘文件————————>内核缓冲区————————>用户缓冲区————————>Socket缓存区————————>网卡

零拷贝实现方案:

  1. mmap+write 4次【上下文切换】+3次【数据拷贝】
  2. sendfile 2次【上下文切换】+3次【数据拷贝】

通过上面两种方法代替传统的read()+write()可以减少【上下文切换】和【数据拷贝】的次数

mmap+write调用次数:两次系统调用

mmap+write拷贝流程: 无需经过内核缓冲区

        DMA拷贝           CPU拷贝               DMA拷贝
磁盘文件————————>内核缓冲区————————>Socket缓存区————————>网卡

sendfile调用次数:只需一次系统调用它可以替代前面的 read () 和 write () 这两个系统调用,这样就可以减少一次系统调用,也就减少了 2 次上下文切换的开销

sendfile拷贝流程:无需经过内核缓冲区

        DMA拷贝           CPU拷贝               DMA拷贝
磁盘文件————————>内核缓冲区————————>Socket缓存区————————>网卡

真正的零拷贝

网卡支持 SG - DMA,sendfile就能实现真正的零拷贝

全程只需要DMA参与不需要CPU

一次系统调用

2次【上下文切换】+3次【数据拷贝】

拷贝流程:盘文件->内核缓冲区->网卡 无需CPU参与,无需经过Socket

         DMA拷贝           DMA拷贝
磁盘文件————————>内核缓冲区————————>网卡

PageCache(内核缓冲区)的作用

「内核缓冲区」实际上是磁盘高速缓存(PageCache)

DMA 把磁盘里的数据搬运到内存里,这样就可以用「读写磁盘」替换成「读写内存」

提高磁盘读写性能: PageCache 来缓存最近被访问的数据,当空间不足时淘汰最久未被访问的缓存

减少磁盘IO:

  1. 【预读功能】+【顺序读】
  2. 内核的 I/O 调度算法会缓存尽可能多的 I/O 请求在 PageCache 中最后「合并」成一个更大的 I/O 请求再发给磁盘

PageCache的缺点

大文件的传输,不应该使用 PageCache,也就是说不应该使用零拷贝技术

缓存被大量文件数据洗刷,几乎不可能利用到PageCache 中缓存的最近被访问的数据

所以大文件传输我们要用【直接IO+异步IO】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值