java nio copy_Java NIO——Zero-copy

技术介绍

零复制(英语:Zero-copy;也译零拷贝)技术是指计算机执行操作时,CPU不需要先将数据从某处内存复制到另一个特定区域,从而可以减少上下文切换及CPU的拷贝时间,通常用于通过网络传输文件时节省CPU周期和内存带宽。

假如我们要实现这样的功能:将文件中的字节复制到套接字中

read(file, tmp_buf, len);

write(socket, tmp_buf, len);

传统实现方式

0_12952361353NK2.gif

过程如下

read()函数调用导致了一次用户态到内核态的上下文切换。系统内部的sys_read()调用被用于把数据读取出来。第一次复制是以DMA引擎的方式呈现的,DMA把数据读取出来并存入kernel address space buffer。

数据被读取返回后导致了上下文从内核态切换到用户态,现在数据存在user address space buffer中。

send()操作再次把上下文从用户态切换到内核态。并且数据被从用户缓存拷贝到kernel address space buffer中。

send()操作返回,这时又从内核态返回到用户态,并且发生最后一次数据拷贝,数据从kernel buffer拷贝到protocol engine中。

这个过程当中一共出现了4次数据拷贝和4次用户态-内核态用户态-内核态上下文切换(每一次系统调用都是两次上下文切换:用户态->内核态->用户态)。

Linux 2.4之前的底层实现

仔细检查上面的流程,其实第二次和第三次复制是不必要的(从buffer到应用程序、从应用程序到buffer),应用程序并没有改变数据内容,只是将其返回到socket buffer中。Java中提供了transferTo()方法,可以让你实现数据直接从read buffer输到 socket buffer。

transferTo() 方法将数据从一个文件channel传输到一个可写channel。在内部它依赖于操作系统对 Zero-copy 的支持,在UNIX/Linux系统上, transferTo() 实际会调用 sendfile() 这个系统函数,将数据从一个文件描述符传输到另一个。

下图展示了使用 transferTo()时的数据拷贝情况

317d7288b44b0f515d78e0bb49e93997.gif

过程如下

transferTo()调用使文件内容通过DMA的方式被复制到read buffer。然后将数据复制到与输出的socket相关的buffer中。

第三次复制发生在DMA将数据复制到protocol engine。

这已经有了改进,我们已将上下文切换次数从四次减少到两次,并将数据拷贝的次数从四次减少到三次(其中只有一次涉及CPU操作)

Linux 2.4之后的底层实现

f1873f4c806d5d5858129ef06bdc7879.gif

过程如下

transferTo方法调用使文件内容通过DMA引擎被复制到kernel buffer

无数据被复制到socket buffer。只是描述了需要被写入的数据的位置和长度。DMA引擎直接把数据从kernel buffer复制到protocol engine

现在整个过程只有两次上下文切换和两次数据拷贝。

在内核为2.4或者以上版本的linux系统上,socket缓冲区描述符将被用来满足这个需求。这个方式不仅减少了内核用户态间的切换,而且也省去了那次需要cpu参与的复制过程。

从用户角度来看依旧是调用transferTo()方法,但是其本质发生了变化:

调用transferTo方法后数据被DMA从文件复制到了内核的一个缓冲区中。

数据不再被复制到socket关联的缓冲区中了,仅仅是将一个描述符(包含了数据的位置和长度等信息)追加到socket关联的缓冲区中。DMA直接将内核中的缓冲区中的数据传输给协议引擎,消除了仅剩的一次需要cpu周期的数据复制。

标签:复制到,DMA,Java,socket,buffer,Zero,内核,copy,数据

来源: https://blog.csdn.net/u013967628/article/details/94848751

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值