LWN: 改善fget()的performance

栏目: 数据库 · 发布时间: 5年前

内容简介:全文完极度欢迎将文章分享到朋友圈长按下面二维码关注:Linux News搬运工,希望每周的深度文章以及开源社区的各种新近言论,能够让大家满意~

Improving fget() performance

By Jake Edge

May 6, 2019

LSFMM

在2019 Linux Storage, Filesystem, and Memory-Management Summit上,Dave Watson提出了一个讨论话题,关于fget()函数的performance。fget()会获取一个文件的struct file指针,reference count加一。用完后,可以通过fput()来释放reference。Watson最近在Facebook的performance分析中,发现这个函数占用了挺多的CPU时间,他分享了一下自己的发现。

在Facebook运行一些service的服务器上,fget()和fput()占用了将近3%的CPU。有一次他看到内部服务占用了2.9%,而 Memcached 的分布式key-value存储服务占用了2%,mcrouter占用了1.7%,其他service一般在0.3%到0.9%。

他起初觉得用这么多CPU时间来做reference count引用计数的维护,也太多了吧。不过后来他发现受到影响的service主要都是networking service,所以他猜测可能是network stack这边导致这个问题的。于是他仔细钻研了一下Memcached,发现fget()和fput()所占用的CPU时间中, 72.5%的时间都是起源于recvfrom() system call。其他还有2个syscall也用了不少fget()时间,分别是epoll_pwait()占了11.5%,sendmsg()占了11%。

LWN: 改善fget()的performance

而Memcached是一个call-response service,也就是说它受到一个request之后,会发送对应的response回去。而sendmsg()就跟recvfrom()被调用的次数是一样多的,却没有出现类似的问题。所以他比较怀疑是receive这条通路上发生了不少cache miss,而send是在这之后紧跟着发生的,因此cache miss发生的更少。

仔细分析fget()之后,发现cache miss来自file-descriptor table,在释放struct file指针的时候,会花费很多CPU时间,还有在atomic increase这个reference count的时候也一样。于是他相应的想了2个方法来改善。首先是针对有些system call,只用了一个file descriptor的话,在fget()的时候先不增长reference count(相应的在fput()的时候也先不减少reference count),例如recvfrom(),sendmsg(),各种epoll*(),都是这个类型的。这样,函数调用的时候一般就不会被阻塞在那里了,不过如果仍然阻塞了的话,就走回原来的处理逻辑。简单实现了一下之后,他发现测试结果不是太理想,所以他就放弃了这条路。

第二个方向,是给struct file的指针创建一个per-task的cache,这样来减少cache miss。在file-descriptor table里面有很多file指针是公用同一个cache line的,只要其中一个指针被某个其他进程改了,整个cache line都会受到影响。Facebook的应用场景里,file descriptor会一直归属于各自的处理线程,所以这个方案能解决Facebook的问题。当然这不是一个official的方案,但是他想先测测有没有想过。不过,还要注意,如果需要close()能正常完成的话,就需要及时flush cache。最后他在struct file里面加了一个指针指向per-task cache entry,这样close()就能正确利用这个信息了。

最终,他的试验证明有效,大多数cache miss的性能损失都不再存在了。系统的performance基本上有2倍的增长。他还没有想好怎么处理struct file dereference的时候的cache miss,应该是下一步了。

Jan Kara担心这里的file-descriptor table问题,是否能通过更改file descriptor的分配方式来解决。就是用不同的thread来分配table里的不同部分。有些application依赖一个排好序的file-descriptor allocation,这种情况就没法支持好了。不过确实这个idea对减少cache line的反复替换还是有帮助的。Matthew Wilcox建议这里可以利用dup2()来达到这个效果。

Wilcox还建议这个改动应该是基于进程的,而不是基于线程的。而Facebook的service的设计也可以再考虑一下这个底层特性,来改善这个问题。Watson回答Facebook service很难改了,不过Jan Kara提出的per-thread file-descriptor range还是值得一试的。

全文完

极度欢迎将文章分享到朋友圈 

长按下面二维码关注:Linux News搬运工,希望每周的深度文章以及开源社区的各种新近言论,能够让大家满意~

LWN: 改善fget()的performance


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

机器学习实战:基于Scikit-Learn和TensorFlow

机器学习实战:基于Scikit-Learn和TensorFlow

Aurélien Géron / 王静源、贾玮、边蕤、邱俊涛 / 机械工业出版社 / 2018-8 / 119.00

本书主要分为两个部分。第一部分为第1章到第8章,涵盖机器学习的基础理论知识和基本算法——从线性回归到随机森林等,帮助读者掌握Scikit-Learn的常用方法;第二部分为第9章到第16章,探讨深度学习和常用框架TensorFlow,一步一个脚印地带领读者使用TensorFlow搭建和训练深度神经网络,以及卷积神经网络。一起来看看 《机器学习实战:基于Scikit-Learn和TensorFlow》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

随机密码生成器
随机密码生成器

多种字符组合密码

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码