[TOC]
转载地址:https://zhuanlan.zhihu.com/p/78869158
转载地址:https://www.cnblogs.com/fengli9998/p/10231329.html
什么是零拷贝
零拷贝(英语: Zero-copy) 技术是指计算机执行操作时,CPU不需要先将数据从某处内存复制到另一个特定区域。这种技术通常用于通过网络传输文件时节省CPU周期和内存带宽。
➢零拷贝技术可以减少数据拷贝和共享总线操作的次数,消除传输数据在存储器之间不必要的中间拷贝次数,从而有效地提高数据传输效率
➢零拷贝技术减少了用户进程地址空间和内核地址空间之间因为上:下文切换而带来的开销
可以看出没有说不需要拷贝,只是说减少冗余[不必要]的拷贝。
零拷贝给我们带来的好处
- 减少甚至完全避免不必要的CPU拷贝,从而让CPU解脱出来去执行其他的任务
- 减少内存带宽的占用
- 通常零拷贝技术还能够减少用户空间和操作系统内核空间之间的上下文切换
零拷贝的实现
零拷贝实际的实现并没有真正的标准,取决于操作系统如何实现这一点。零拷贝完全依赖于操作系统。操作系统支持,就有;不支持,就没有。不依赖Java本身。
Kafka Netty rocketmq nginx apache
上面这些组件都使用了。
io读写的方式
中断
1. 用户进程发起数据读取请求
2. 系统调度为该进程分配cpu
3. cpu向io控制器(ide,scsi)发送io请求
4. 用户进程等待io完成,让出cpu
5. 系统调度cpu执行其他任务
6. 数据写入至io控制器的缓冲寄存器
7. 缓冲寄存器满了向cpu发出中断信号
8. cpu读取数据至内存
缺点:中断次数取决于缓冲寄存器的大小
用户进程需要读取磁盘数据,需要CPU中断,发起IO请求,每次的IO中断,都带来CPU的上下文切换。
因此出现了——DMA
DMA-直接内存存取
DMA(Direct Memory Access,直接内存存取) 是所有现代电脑的重要特色,它允许不同速度的硬件装置来沟通,而不需要依赖于CPU 的大量中断负载。
DMA控制器,接管了数据读写请求,减少CPU的负担。这样一来,CPU能高效工作了。 现代硬盘基本都支持DMA。
1. 用户进程发起数据读取请求
2. 系统调度为该进程分配cpu
3. cpu向DMA发送io请求
4. 用户进程等待io完成,让出cpu
5. 系统调度cpu执行其他任务
6. 数据写入至io控制器的缓冲寄存器
7. DMA不断获取缓冲寄存器中的数据(需要cpu时钟)
8. 传输至内存(需要cpu时钟)
9. 所需的全部数据获取完毕后向cpu发出中断信号
优点:减少cpu中断次数,不用cpu拷贝数据
传统方式数据拷贝
- 下面展示了 传统方式读取数据后并通过网络发送 所发生的数据拷贝:
1. 一个read系统调用后,DMA执行了一次数据拷贝,从磁盘到内核空间
2. read结束后,发生第二次数据拷贝,由cpu将数据从内核空间拷贝至用户空间
3. send系统调用,cpu发生第三次数据拷贝,由cpu将数据从用户空间拷贝至内核空间(socket缓冲区)
4. send系统调用结束后,DMA执行第四次数据拷贝,将数据从内核拷贝至协议引擎
5. 另外,这四个过程中,每个过程都发生一次上下文切换
- 内存缓冲数据,主要是为了提高性能,内核可以预读部分数据,当所需数据小于内存缓冲区大小时,将极大的提高性能。
- 零拷贝是为了消除这个过程中冗余的拷贝
零拷贝-sendfile 对应到java中
//将数据从文件通道传输到了给定的可写字节通道
为FileChannel.transferTo(long position, long count, WritableByteChannel target)
-
避免了第2,3步的数据拷贝,参考下图:
1. DMA从拷贝至内核缓冲区
2. cpu将数据从内核缓冲区拷贝至内核空间(socket缓冲区)
3. DMA将数据从内核拷贝至协议引擎
4. 这三个过程中共发生2次上下文切换,分别为发起读取文件和发送数据
- 以上过程发生了三次数据拷贝,其中有一次为cpu完成
- linux内核2.4以后,socket缓冲区做了调整,DMA带收集功能,如下图:
1. DMA从拷贝至内核缓冲区
2. 将数据的位置和长度的信息的描述符增加至内核空间(socket缓冲区)
3. DMA将数据从内核拷贝至协议引擎
所谓零拷贝,指的是应用内存与内核内存不存在拷贝。
零拷贝-mmap
零拷贝-sendFile
mmap和sendFile的区别
「真诚赞赏,手留余香」