Zore copy(翻译《Efficient data transfer through zero copy》)
原文: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。
下图展示整个过程中数据的拷贝:

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

过程如下:
- read()函数调用导致了一次用户态到内核态的上下文切换。系统内部的sys_read()调用被用于把数据读取出来。第一次复制是以DMA引擎的方式呈现的,DMA把数据读取出来并存入kernel address space buffer。
- 数据被读取返回后导致了上下文从内核态切换到用户态,现在数据存在user address space buffer中。
- send()操作再次把上下文从用户态切换到内核态。并且数据被从用户缓存拷贝到kernel address space buffer中。
- 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方法是发生的步骤如下:
- transferTo()调用使文件内容通过DMA的方式被复制到read buffer。然后将数据复制到与输出的socket相关的buffer中。
- 第三次复制发生在DMA将数据复制到protocol engine。
整个过程相对于传统方式减少了两次上下文切换和一次数据拷贝。
但这还没有达到zero-copy的目标。如果底层网络接口支持,我们可以进一步减少数据拷贝。在Linux内核2.4及之后版本,socket buffer支持了这种方式:
- transferTo方法调用使文件内容通过DMA引擎被复制到kernel buffer
- 无数据被复制到socket buffer。只是描述了需要被写入的数据的位置和长度。DMA引擎直接把数据从kernel buffer复制到protocol engine

整个过程现在只有两次上下文切换和两次数据拷贝。
两种方式的性能对比:

Zore copy(翻译《Efficient data transfer through zero copy》)的更多相关文章
- Efficient data transfer through zero copy
Efficient data transfer through zero copy https://www.ibm.com/developerworks/library/j-zerocopy/ Eff ...
- PatentTips - Cross-domain data transfer using deferred page remapping
BACKGROUND OF THE INVENTION The present invention relates to data transfer across domains, and more ...
- ABAP术语-Data Transfer
Data Transfer 原文:http://www.cnblogs.com/qiangsheng/archive/2008/01/22/1048286.html The entire proces ...
- PatentTips – RDMA data transfer in a virtual environment
BACKGROUND Embodiments of this invention relate to RDMA (remote direct memory access) data transfer ...
- OpenHCI - Data Transfer Types
There are four data transfer types defined in USB(USB中有4种数据传输类型). Each type is optimized to match th ...
- UDT: Breaking the Data Transfer Bottleneck
http://udt.sourceforge.net/ DT is a reliable UDP based application level data transport protocol for ...
- 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 ...
- Data transfer object
Data transfer object (DTO) is a design pattern used to transfer data between software application su ...
- 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 ...
随机推荐
- STM32的USART DMA传输(转)
源:STM32的USART DMA传输 问题描述: 我有一个需求,AD采得一定数目的数据之后,由串口DMA发出,由于AD使用双缓冲,所以每次开始DMA的时候都需要重新设置开始的内存地址以及传输的数目( ...
- FZU 1397 保送
网络流入门题. 源点到每一个学生连一条边,容量为1 每个学校到汇点连一条边,容量为L 符合要求的学生和学校之间连边,容量为1. 从源点到汇点的最大流就是答案. #include<cstdio&g ...
- UVA 1386 Cellular Automaton
矩阵快速幂. 样例是这样构造矩阵的: 矩阵很好构造,但是500*500*500*logk的复杂度显然是无法通过这题的. 其实本题构造出来的矩阵是一个循环矩阵,只需直到第一行或者第一列,即可直到整个矩阵 ...
- Bootstrap兼容处理
接将一下代码引用到页面 </body> 之前 <script src="//cdn.bootcss.com/jquery/1.11.3/jquery.min.js" ...
- ucos任务优先级从64到256,任务就绪表的改变
Ucos在任务调度中经常使用的技术为任务就绪表,在之前的文章中使用的例子是低于64个优先级的任务就绪表查找方法,现在ucos将任务扩展到256优先级之后,任务就绪表的查找也做了一定的修改,今天来讲讲 ...
- 编译时.test文件报错无法解决的方法,关闭test编译
有几次遇到从网上下载到的iOS开源代码编译报错,报错位置为Test Target的源文件,我就挺奇怪我又没做测试为啥会编译Test Target的源文件,之前的暴力解决方法是把Test Target直 ...
- 从字符串拼接看JS优化原则
来自知乎的问题:JavaScript 怎样高效拼接字符串? 请把以下用于连接字符串的JavaScript代码修改为更高效的方式: var htmlString ='< div class=”co ...
- python 自动化之路 day 14
今日内容 http://www.cnblogs.com/wupeiqi/articles/5699254.html 群共享 s15Html课件 1. paramiko模块 https://github ...
- spark连接mongodb
1.添加依赖 hadoop和mongodb的连接器 <dependency> <groupId>org.mongodb.mongo-hadoop</groupId> ...
- 最简化模型2——css3分阶段动画效果(经过实测)之转动的div
@keyframes mymove{ 0%{top: 0;left: 0;transform:rotate(50deg);} 10%{top: 100px;left: 50px;trans ...