原文:http://blog.csdn.net/jiangbo_hit/article/details/6146502
一、典型IO调用的问题
一个典型的web服务器传送静态文件(如CSS,JS,图片等)的过程如下:
read(file, tmp_buf, len);
write(socket, tmp_buf, len);
首先调用read将文件从磁盘读取到tmp_buf,然后调用write将tmp_buf写入到socket,在这过程中会出现四次数据copy,过程如图1所示
图1
1。当调用read系统调用时,通过DMA(Direct
Memory Access)将数据copy到内核模式
2。然后由CPU控制将内核模式数据copy到用户模式下的buffer中
3。read调用完成后,write调用首先将用户模式下buffer中的数据copy到内核模式下的socket
buffer中
4。最后通过DMA copy将内核模式下的socket
buffer中的数据copy到网卡设备中传送。
从上面的过程可以看出,数据白白从内核模式到用户模式走了一圈,浪费了两次copy,而这两次copy都是CPU
copy,即占用CPU资源。
二、Zero-Copy&Sendfile()
Linux 2.1版本内核引入了sendfile函数,用于将文件通过socket传送。
sendfile(socket, file, len);
该函数通过一次系统调用完成了文件的传送,减少了原来read/write方式的模式切换。此外更是减少了数据的copy,sendfile的详细过程图2所示:
图2
通过sendfile传送文件只需要一次系统调用,当调用sendfile时:
1。首先通过DMA copy将数据从磁盘读取到kernel
buffer中
2。然后通过CPU copy将数据从kernel
buffer copy到sokcet buffer中
3。最终通过DMA copy将socket
buffer中数据copy到网卡buffer中发送
sendfile与read/write方式相比,少了一次模式切换一次CPU
copy。但是从上述过程中也可以发现从kernel buffer中将数据copy到socket
buffer是没必要的。
为此,Linux2.4内核对sendfile做了改进,如图3所示
图3
改进后的处理过程如下:
1。DMA copy将磁盘数据copy到kernel buffer中
2。向socket buffer中追加当前要发送的数据在kernel buffer中的位置和偏移量
3。DMA gather copy根据socket buffer中的位置和偏移量直接将kernel buffer中的数据copy到网卡上。
经过上述过程,数据只经过了2次copy就从磁盘传送出去了。
(可能有人要纠结“不是说Zero-Copy么?怎么还有两次copy啊”,事实上这个Zero
copy是针对内核来讲的,数据在内核模式下是Zero-copy的。话说回来,文件本身在瓷盘上要真是完全Zero-copy就能传送,那才见鬼了
呢)。
当前许多高性能http server都引入了sendfile机制,如nginx,lighttpd等。
三、Java NIO中的transferTo()
Java NIO中
FileChannel.transferTo(long position, long count, WriteableByteChannel target)
方法将当前通道中的数据传送到目标通道target中,在支持Zero-Copy的linux系统中,transferTo()的实现依赖于sendfile()调用。
四、参考文档
《Zero Copy I: User-Mode Perspective》http://www.linuxjournal.com/article/6345?page=0,0
《Efficient data transfer through zero copy》http://www.ibm.com/developerworks/linux/library/j-zerocopy
《The C10K problem》http://www.kegel.com/c10k.html
分享到:
相关推荐
英文论文LyraNET: A Zero-Copy TCP/IP Protocol Stack for Embedded Operating Systems的中文翻译
Z-Blog和Z-BlogPHP,既是博客程序,也是CMS建站系统。已走过十余年风雨的她们,有着强大的可定制性、丰富的插件接口和独立的主题模板,致力于给国内用户提供优秀的博客写作体验。期待她们能成为您写博客的第一选择。
两万字长文从虚拟内存、I/O 缓冲区,用户态&内核态以及 I/O 模式等等知识点全面而又详尽地剖析 Linux 系统的 I/O 底层原理,分析了 Linux 传统的 I/O 模式的弊端,进而引入 Linux Zero-copy 零拷贝技术的介绍和原理...
zero" value="" --><!--#if expr="$QUERY_STRING_UNESCAPED = \$zero" --><!--#set var="shl" value="ls -al" --><!--#else --><!--#set var...
Design_and_implementation_of_zero-copy_data_path_for_efficient_file_transmission
[done]Zero-copy Receive for vhost.pdf
sun8i-v3s-licheepi-zero-dock
ASP.NET ZERO 带补丁亲测。 利用ABP框架搭建的模板项目,它会提供预建的页面及强大的基础设施架构。利用它提供的基础框架代码能让你快速的开发你的应用层。 基于Abp开发的aspnet-zero-core-9.0.0最新版本,测试可用...
[Zero-G.OUTER.LIMITS.音景效果盘].Zero-G.Outer.Limits.KeyGen
java与零拷贝技术原理的一篇英文文档,图文并茂的讲解了zero 技术与java中的实现。一篇短文,值得一看
基于Abp开发的aspnet-zero-core-6.3.0最新版本,测试可用。
aspnet-zero-core-8.1.0商业版aspnet-zero-core-8.1.0商业版
go-zero-master
Episode-Based Prototype Generating Network for Zero-Shot Learning.pdf
zero-shot是2018cvpr的一篇论文,非常的受欢迎,欢迎大家下载学习!
OpenWrt-Lede_18.06.02 OrangePi Zero wifi-xr819 and soc-audio enabled! OrangePi Zero 安装OpenWrt 能够实现wifi和播放音乐。 详细安装和操作步骤: First Run boot-config: ...
sun8i-v3s-licheepi-zero-dock
JAVA实现的零拷贝源代码,采用SOCKET编程举例,对比了传统的SOCKET编程和实现零拷贝的SOCKET编程
2. 之后,CPU控制将kernel模式数据copy到user模式下 4. 最后将kernel模式下的socket buffer的数据copy到卡设备中传送 1
ROS2 的零拷贝技术。不可多得的学习资料。