注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

gmd20的个人空间

// 编程和生活

 
 
 

日志

 
 

Linux 的 splice 和sendfile系统调用  

2012-09-26 13:57:42|  分类: linux相关 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

都是为了减少用户和内核直接的数据复制的, 就是所谓的 “zero copy”。


普通的 read 和write系统调用,数据需要从内核空间复制到用户空间的。 


sendfile

      http://linux.die.net/man/2/sendfile 

      http://lxr.linux.no/linux+v3.5.4/fs/read_write.c#L1000 

      在两个文件描述符之间传输数据,不用拷贝。  但 输入的描述符必须是真正的文件, 输出的文件描述符可以是 socket。 这也是sendfile的由来吧。他是从文件的缓存页 page cache里面直接把数据传输到另外一个描述符里面去,省去用户空间和内核空间的复制。 看当前代码他是使用一个专门的do_splice_direct 函数来实现的。 思路跟 splice是一样的,也需要使用pipe来做中介,但他这个do_splice_direct  使用一个每个进程缓存(在 corrent指针的 splice_pipe)的一个pipe,可以少用一次系统调用(正常的splice需要从  文件到 pipe,然后再从pipe到socket,有两次调用)。

      这个sendfile应用场合,比如像http服务器,直接把htm源文件读出来发送给客户可对应的socket时,用这个sendfile就很合适。减少数据复制的同时,应该 系统调用的次数也减少了。  看网上共识,这种应用环境使用sendfile可以提到性能是不争的事实。


splice  

      http://linux.die.net/man/2/splice 

      http://lwn.net/Articles/119680/ 

      http://yarchive.net/comp/linux/splice.html 

      http://lxr.linux.no/linux+v3.5.4/fs/splice.c 

      在两个文件描述符之间传输数据,不用拷贝。但输入和输出文件描述符必须有一个是pipe。也就是说如果你需要从一个socket 传输数据到另外一个socket,是需要使用 pipe来做为中介的。 pipe buffer被抽象出来,当作 “内核缓存结构”, 一种流缓冲,可以理解成你的数据从写入 “内核流缓存”里面,然后在从 一个”内核流缓存“复制到另外一个比如说socket的缓存。全部数据都是在内核空间进行。 当然你的数据复制也是不用复制,他那个pipe buffer本来就是 使用page去管理缓存的,就是 缓存地址加偏移地址的办法,只是Linus 觉splice的需要很像之前的pipe思想,所以splice就用这个个pipe来作为”内核缓存结构“了。

      看起来splice是可以避免数据的复制,应该能获得更好的性能。但好像网上的评测,一些人使用了splice之后性能反而下降。其实大家最想要的还是从socket到socket的 ”零拷贝“技术,这样那些代理服务器啊什么的转发数据的时候就可以提高性能。但这个splice用到这个场合的话, 还是需要一个pipe来做中介的,要调用两个splice才能把数据从一个socket移到另外一个socket。

         splice (socket1_fd,  pipe_fd

         splice (pipl_fd, socket2_fd

这样,系统调用同样需要两次。read write也需要两次。系统调用次数没有减少,不像sendfile那样可以减少一个系统调用。  数据复制的代价,可能数据包比较小时,影响应该是比较小的,所以 splice没有起到意想的作用。有人用性能工具比较了splice的时候的内核调用的区别,说只是性能消耗的地方转移了而已。这个需要那个高人来使用最新的内核测试分析一下了。

        haproxy有配置使不使用splice的选项,splice的使用也可以去参考一下 haproxy的代码。



  评论这张
 
阅读(1289)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017