原文:https://www.ibm.com/developerworks/library/j-zerocopy/

《Efficient data transfer through zero copy》

本文描述通过一种叫做Zore Copy的技术来提升运行在Linux和UNIX上的Java程序的IO性能。

Zero copy避免冗余的数据拷贝并减少用户态和内核态之间的上下文切换。

很多WEB应用都服务大量的静态文件,这些静态文件大多从磁盘读取并返回到socket中。这些操作需要相对较少的CPU,但是比较低效:kernel读取磁盘数据并通过用户态返回给应用,之后应用通过用户态把数据写到socket。事实上,应用作为一个低消的中间介质将数据从磁盘读取并返回给socket。

每一次通过用户态的数据传输,数据都必须要被复制,并且消耗CPU核内存带宽。幸运的是可以通过zore copy来减少拷贝次数。使用zore copy要求内核直接从磁盘复制数据并写入socket,而不通过应用程序。Zero copy减少用户态和内核态的上下文切换,减少拷贝次数来提升性能。

Java类库通过Linux和UNIX系统的tranferTo()来支持zore copy。可以通过transferTo()方法直接从一个channel写到目标channel,并不需要数据通过应用程序。本文首先说明用传统方法传输简单文件的过高开销,然后展示如何通过zore copy的transferTo()方法来获得更好的性能。

Data transfer: Thre traditional approach

考虑读取一个文件并通过网络传输到另一个程序,其核心的操作如list 1中所示。

File.read(fileDesc, buf, len);

Socket.send(socket, buf, len);

主要就是读取文件内容到buffer中,之后将buffer数据发送到socket。

下图展示整个过程中数据的拷贝:

下图展示整个过程中上下文的切换:

过程如下:

  1. read()函数调用导致了一次用户态到内核态的上下文切换。系统内部的sys_read()调用被用于把数据读取出来。第一次复制是以DMA引擎的方式呈现的,DMA把数据读取出来并存入kernel address space buffer。
  2. 数据被读取返回后导致了上下文从内核态切换到用户态,现在数据存在user address space buffer中。
  3. send()操作再次把上下文从用户态切换到内核态。并且数据被从用户缓存拷贝到kernel address space buffer中。
  4. send()操作返回,这时又从内核态返回到用户态,并且发生最后一次数据拷贝,数据从kernel buffer拷贝到protocol engine中。

传统的方式一共出现了4次数据拷贝和上下文切换(每一次系统调用都是两次上下文切换:用户态->内核态->用户态)。

中间kernel buffer的使用时低效的。kernel buffer预期是用于提升性能的,当数据大小没有达到buffer大小时,kernel buffer作为“预读取”的角色提升性能。在写的时候buffer允许异步完成操作。

不幸的是,如果请求数据比buffer还大,那么这个方式本身就会成为瓶颈。数据需要在磁盘,kernel buffer,user buffer间多次拷贝才能到达应用程序。

Zero Copy通过减少不必要的数据拷贝来提升性能。

Data transfer: The zero-copy approach

回顾传统的方式,第二次和第三次复制是不必要的(从buffer到应用程序、从应用程序到buffer),应用程序并没有改变数据内容,只是将其返回到socket buffer中。transferTo实现了数据直接共read buffer到write buffer。

public void transferTo(long position, long count, WritableByteChannel target);

transferTo方法吧数据从file channel传输到

下图展示了通过transferTo()方法中的数据拷贝:

下图展示了通过transferTo()方法中间的上下文切换:

调用transferTo方法是发生的步骤如下:

  1. transferTo()调用使文件内容通过DMA的方式被复制到read buffer。然后将数据复制到与输出的socket相关的buffer中。
  2. 第三次复制发生在DMA将数据复制到protocol engine。

整个过程相对于传统方式减少了两次上下文切换和一次数据拷贝。

但这还没有达到zero-copy的目标。如果底层网络接口支持,我们可以进一步减少数据拷贝。在Linux内核2.4及之后版本,socket buffer支持了这种方式:

  1. transferTo方法调用使文件内容通过DMA引擎被复制到kernel buffer
  2. 无数据被复制到socket buffer。只是描述了需要被写入的数据的位置和长度。DMA引擎直接把数据从kernel buffer复制到protocol engine

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

两种方式的性能对比:

Zore copy(翻译《Efficient data transfer through zero copy》)的更多相关文章

  1. Efficient data transfer through zero copy

    Efficient data transfer through zero copy https://www.ibm.com/developerworks/library/j-zerocopy/ Eff ...

  2. PatentTips - Cross-domain data transfer using deferred page remapping

    BACKGROUND OF THE INVENTION The present invention relates to data transfer across domains, and more ...

  3. ABAP术语-Data Transfer

    Data Transfer 原文:http://www.cnblogs.com/qiangsheng/archive/2008/01/22/1048286.html The entire proces ...

  4. PatentTips – RDMA data transfer in a virtual environment

    BACKGROUND Embodiments of this invention relate to RDMA (remote direct memory access) data transfer ...

  5. OpenHCI - Data Transfer Types

    There are four data transfer types defined in USB(USB中有4种数据传输类型). Each type is optimized to match th ...

  6. UDT: Breaking the Data Transfer Bottleneck

    http://udt.sourceforge.net/ DT is a reliable UDP based application level data transport protocol for ...

  7. ISO 9141-2 and ISO 14230-2 INITIALIZATION and DATA TRANSFER

    http://ecad.tu-sofia.bg/et/2005/pdf/Paper097-P_Dzhelekarski1.pdf INITIALIZATION Prior to any diagnos ...

  8. Data transfer object

    Data transfer object (DTO) is a design pattern used to transfer data between software application su ...

  9. Data transfer from GPIO port to RAM buffer using DMA upon receiving a trigger signal on the timer capture input channel.

    Data transfer from GPIO port to RAM buffer using DMA upon receiving a trigger signal on the timer ca ...

随机推荐

  1. stm8的独立看门狗与窗口看门狗

    STM8拥有两个硬件看门狗,分别叫做独立看门狗和窗口看门狗 独立看门狗的框图如下 我们可以看到,独立看门狗的时钟来自于LSI内部低速振荡器,经过二分频到达看门狗外设单元,在经过一个七位的预分频到达计数 ...

  2. Linux下部署

    moto66@163.com       0144586wei 郭 2015/3/23 星期一 9:29:38 服务器密码:0144586Wei120.26.62.247

  3. struts2拦截器-自定义拦截器,放行某些方法(web.xml配置)

    一.web.xml配置 <filter> <filter-name>encodingFilter</filter-name> <filter-class> ...

  4. .net面试题【持续更新.....】

    1.C#中readonly和const的区别? 2.C#中的排序继承自哪个接口?Icompare 3.阐述单点登录的实现原理? 4.C#中property和Attribute的区别? 5.Datase ...

  5. [原]崩溃在ole32!CStdMarshal::DisconnectSrvIPIDs

    最近项目里遇到一个崩溃,不定期出现,很是头疼!今晚终于忍无可忍,下决心要干掉它!(于是用凉水洗了把脸,开始分析dump)希望凌晨的这篇总结对有相似经历的朋友有所启发!(看之前相关的几个dump可以猜到 ...

  6. android TextView实现滚动显示效果

    在android中,如果设置了TextView控件为单行显示,且显示的文本太长的话,默认情况下会造成显示不全的情况,这种情况下我们需要设置该控件属性如下: <TextView android:i ...

  7. HNU 13081 Even Up Solitaire解题报告

    题目大意:给定一个数组,若相邻的两个数之和为偶数,则将此两个数移除,通过这种方法将满足条件得数移除后数组还剩多少个数. 此题太水,不做解释.直接代码之: #include <stdio.h> ...

  8. swift button一些简单设置

    1,按钮的创建(1)按钮有下面四种类型: UIButtonType.ContactAdd:前面带“+”图标按钮,默认文字颜色为蓝色,有触摸时的高亮效果 UIButtonType.DetailDiscl ...

  9. AFNetWorking 之 网络请求的基本知识

    NSString *urlStr = @"http://api.openweathermap.org/data/2.5/forecast/daily"; AFHTTPRequest ...

  10. 滚轮事件的防冒泡、阻止默认行为的代码(效果是:只让当前div滚动,连当前文档都不滚动的效果)

    //用firefox变量表示火狐代理var firefox = navigator.userAgent.indexOf('Firefox') != -1;function MouseWheel(e){ ...