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 ...
随机推荐
- java.lang.ClassNotFoundException: org.apache.commons.pool2.impl.GenericObjectPoolConfig
问题描述: Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with n ...
- leetcode-004 insertion sort list
package leetcode; class ListNode { int val; ListNode next; ListNode(int x) { val = x; next = null; } ...
- Swift迁入第三方库时的版本错误解决
我的swift的项目用的是swift 2.3的版本,但是用CocoaPods迁入一个第三方:ObjectMapper后,编译会出现这样一个问题: Use Legacy Swift Language V ...
- TCP/IP详解--拥塞控制 & 慢启动 快恢复 拥塞避免
TCP的拥塞控制 1. 拥塞:即对资源的需求超过了可用的资源.若网络中许多资源同时供应不足,网络的性能就要明显变坏,整个网络的吞吐量随之负荷的增大而下降. 拥塞控制:防止过多的数据注入到网络中,这样 ...
- Reactive 网络状态 Activity indicator view
转动属性:Animating RAC(self.searchActivity, hidden) = [self.m_viewModel.m_searchCommand.executing not];
- iOS 开发 之 编程知识点
iOS 创建和设置pch iOS 之 时间格式与字符串转换 iOS 之 二维码生成与扫描(LBXScan) iOS 之 定时器 iOS 之 通知 iOS 之 NSString 去除前后空格和回车键 i ...
- ThinkPHP创建应用的一般开发流程
使用ThinkPHP创建应用的一般开发流程是: 系统设计.创建数据库和数据表:(可选) 项目命名并创建项目入口文件,开启调试模式: 完成项目配置: 创建项目函数库:(可选) 开发项目需要的扩展(模式. ...
- Delphi中解析Xml的控件-SimDesign NativeXml
Delphi中解析Xml的控件-SimDesign NativeXml 正在学习,感觉应用很方便.无源代码的版本还是免费的. SimDesign.NativeXml是一个delphi和bcb的XML控 ...
- DBGrid 各属性的设置
在 Delphi 语言的数据库编程中,DBGrid 是显示数据的主要手段之一.但是 DBGrid 缺省的外观未免显得单调和缺乏创意.其实,我们完全可以在我们的程序中通过编程来达到美化DBGrid 外观 ...
- mysql 自带的压力测试
注意mysqlslap 是mysql5.1之后新添加的功能,之前的版本是没有此功能的