浅谈Linux的零拷贝技术

>,在Linux系统内部缓存和内存容量都是有限的,更多的数据都是存储在磁盘中。对于Web服务器来说经常需要从磁盘中读取数据到内存,然后再通过网卡传输给用户:,浅谈Linux的零拷贝技术,那么这也算一次I O的过程,都知道IO过程中需要状态的切换还有一系列拷贝过程,都是要时间开销的,那么怎么优化用户态和内核态的状态的切换次数和各种缓冲区之间的拷贝次数,也是linux的服务器实现高并发的重要技术了!,传统 io 的执行流程: 下面将图左半部分read过程的硬件抽象为磁盘; 图右半部分write过程的硬件设为网卡,模拟webserver进行一次IO的过程; 方便理解;,read/write 属于系统调用 syscall,每一次系统调用 ,发生两次上下文切换,如图所示,传统 io 的过程中,发生了4次空间切换 + 4次拷贝,浅谈Linux的零拷贝技术,不难看出,传统模式下的IO,涉及多次空间切换和数据冗余拷贝,效率并不高。而零拷贝 Zero-Copy 目的就是降低冗余数据拷贝,解放 CPU,目前来看,零拷贝技术的实现手段主要包括:mmap+write、sendfile、sendfile+DMA、splice,首先解释一下,零拷贝中的0,指的是CPU级别的数据拷贝(比如内核缓冲区到用户缓冲区的拷贝,用户缓冲区再到socket缓冲区; 或者内核缓冲区直接到socket缓冲区的拷贝!),并不是DMA硬件的拷贝,否则数据不靠DMA怎么转移呢?,mmap可以充当read的功能,将内核读缓冲区地址与用户缓冲区地址进行映射,实现内核缓冲区与用户缓冲区的共享。这样就减少了一次用户态和内核态的CPU拷贝。,mmap + write 流程如图所示,发生了4次切换 + 2次DMA拷贝 + 1次CPU拷贝,浅谈Linux的零拷贝技术,函数原型,例: 发送方:,接收方:,小结,mmap充当read的功能,进行一次完整的IO,减少了传统方式read数据的时候,从内核态CPU拷贝到用户态的这次拷贝; (发生了4次切换 + 2次DMA拷贝 + 1次CPU拷贝;),mmap+write 方式有一定改进,但是由系统调用引起的状态切换并没有减少,因此在 Linux 内核2.1版本中引入了 sendfile 系统调用。,sendfile 在两个文件之间通过内核直接传输数据,避免了内核缓冲区和用户缓冲区之间的数据拷贝操作。sendfile 只能用于发送数据,不能用于接收数据。,sendfile 方式只使用一个函数就可以完成之前的 read+write 和 mmap+write 的功能,这样减少一个系统调用(2次状态切换),由于数据不经过用户缓冲区,因此该数据无法被修改。,sendfile 的流程如图所示, 发生了2次切换 + 2次DMA拷贝+1次CPU拷贝,浅谈Linux的零拷贝技术,linux2.4版本后,对 sendfile 系统调用进行优化,配合硬件 DMA,可以直接从内核空间缓冲区中将数据拷贝到网卡,彻底省去了CPU拷贝。,如图所示,sendfile + DMA 的过程中发生了2次切换 + 2次DMA拷贝 + 0次CPU拷贝,浅谈Linux的零拷贝技术,sendfile 函数原型,例:,发送方,小结,早期sendfile : 2次切换 (sendfile后,数据不用过用户层了,导致不能修改了,不过也少了两次状态切换!)+ 2次DMA拷贝(磁盘到内核,socket缓冲区到网卡)+ 1次CPU拷贝(内核到socket缓冲区),改良的sendfile + DMA : 发生了2次切换 + 2次DMA拷贝(磁盘到内核,内核直接到网卡) + 0次CPU拷贝,splice 系统调用在 Linux 2.6 版本引入,不需要硬件支持,并且不再限定于 socket 上,实现了两个普通文件之间的零拷贝。,可以在内核缓冲区和 socket 缓冲区间建立管道来传输数据避免了两者之间的 CPU 拷贝操作。,浅谈Linux的零拷贝技术,函数原型,例:web服务器端代码: transFile.c:,小结,splice 引入管道机制,实现了普通文件之间的0拷贝,突破了仅限于socket的sendfile0拷贝;,>
返回顶部
跳到底部

Copyright 2011-2024 南京追名网络科技有限公司 苏ICP备2023031119号-6 乌徒帮 All Rights Reserved Powered by Z-BlogPHP Theme By open开发

请先 登录 再评论,若不是会员请先 注册