NIO中的零拷贝--transferTo

 1、我们说零拷贝,是从操作系统的角度来说的。因为内核缓冲区之间,没有数据是

重复的(只有 kernel buffer 有一份数据)。

2、零拷贝不仅仅带来更少的数据复制,还能带来其他的性能优势,例如更少的上下

文切换,更少的 CPU 缓存伪共享以及无 CPU 校验和计算。

(DMA--Direct memory access-直接内存拷贝)

①传统的io流是需要经历这样的过程:

用户态--DMA拷贝--内核态--CPU拷贝--用户Buffer--CPU拷贝--SocketBuffer--DMA拷贝--协议栈

经历了4次拷贝,4次状态切换

②后面出现了mmap:

mmap 通过内存映射,将文件映射到内核缓冲区,同时,用户空间可以共享内核

空间的数据。这样,在进行网络传输时,就可以减少内核空间到用户控件的拷贝

次数

用户态--DMA拷贝--内核态--改成直接读取--用户Buffer--CPU拷贝--SocketBuffer--DMA拷贝--协议栈

经历了3次拷贝,4次状态切换,但是还是有cpu拷贝

③Linux 2.1 版本 提供了sendFile 函数,其基本原理如下:数据根本不经过用户态,直接从内核缓冲区进入到 SocketBuffer,同时,由于和用户态完全无关,就减少了一次上下文切换

用户态--DMA拷贝--内核态--CPU拷贝--SocketBuffer--DMA拷贝--协议栈

经历了3次拷贝,3次状态切换,这里的CPU拷贝是极少的,就一些length,Offset的状态拷贝,接近于零拷贝了。

Linux 在 2.4 版本中,做了一些修改,避免了从内核缓冲区拷贝到 Sockebuffer 的操作,直接拷贝到协议栈,从而再一次减少了数据拷贝。

用户态--DMA拷贝--内核态--CPU拷贝--DMA拷贝--协议栈

经历了3次拷贝,2次状态切换,这里的CPU拷贝是极少的,就一些length,Offset的状态拷贝,接近于零拷贝了。

这里总结一下mmap和sendFile的区别:

1) mmap 适合小数据量读写,sendFile 适合大文件传输。

2) mmap 需要 4 次上下文切换,3 次数据拷贝;sendFile 需要 3 次上下文切换,最

少 2 次数据拷贝。

3) sendFile 可以利用 DMA 方式,减少 CPU 拷贝,mmap 则不能(必须从内核拷贝

到 Socket 缓冲区)。

下面就来讲讲如何使用nio的transferto来实现零拷贝:

用户--DMA---channel----DMA---对方文件

linux中,使用transferto可以完成整个文件的传输,但是在window中,transferto一次只能发送8m的文件,就需要分片传输,注意传输起点(8*1024*1024)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值