前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[linux][memory]ksm/uksm的调优和优化尝试

[linux][memory]ksm/uksm的调优和优化尝试

作者头像
皮振伟
发布2018-04-09 10:13:06
2.5K0
发布2018-04-09 10:13:06
举报
文章被收录于专栏:皮振伟的专栏皮振伟的专栏

前言: 在前文《[linux][memory]KSM技术分析》中,分析了KSM技术的基本实现原理。这里再总结一下使用ksm/uksm遇到的几个问题,并附加上作者对性能优化的尝试。

分析: 1,20M linux-4.0.4/mm/ksm.c中代码:

在ksm扫描page并尝试做merge的主要逻辑中,注意两个参数:ksm_thread_pages_to_scan,默认值是100,也就是说,每次loop中最多可以merge100个page,也就是100 × 4K = 400K;ksm_thread_sleep_millisecs默认值是20,也就是说,两次loop的时间间隔是20ms。 那么每秒钟可以merge的page数目,计算一下就是:4K × 100 / 0.02 约等于20M。 所以会看到uksm的性能可以甩ksm好几条街的情况了。cat /sys/kernel/mm/ksm/pages_to_scan用来确认当前的 ksm_thread_pages_to_scan,cat /sys/kernel/mm/ksm/sleep_millisecs来确认当前的ksm_thread_sleep_millisecs。 2,1G 通过增大/sys/kernel/mm/ksm/pages_to_scan和减小/sys/kernel/mm/ksm/sleep_millisecs,可以让ksm的能力大约提升到1G这个数量级(当然和CPU有关,单核能力越强,则合并越快,不过大约这个数量级,不会相差太多),不过相应的CPU会吃的比较高。 在IaaS使用的服务器上,CPU基本都在64Core以上,单核吃到50%,并且做好资源隔离,应该不是什么大问题。 3,KSM VS UKSM 不可避免的,要对比ksm和uksm。总体来说,uksm更快一些。单纯的比较合并速度,uksm有两个地方会更快一些: a,uksm对zero page的优化。在启动虚拟机的时候,尤其是windows,会初始化把内存都踩成0,那么就会有大量的zero page。uksm在处理zero page的时候,会有汇编加速,代码选自https://github.com/dolohow/uksm/blob/master/uksm-4.0.patch:

作者做的实验结果表明,这里的效果很明显。 b,先看一下ksm的stable tree的组织:

每个节点上都是一个page,无论是查找还是插入,在stable tree中比较的过程中,通过一级一级的memcpy比较两个page的数值大小进行操作。 在uksm的stable tree的组织:

先计算出来待操作page的hash值,搜索tree的过程中,进行整形数值比较就能找到对应的节点的位置。大大减少了memcmp的次数。 当然,uksm和ksm还有其他方面的差异,比如说,ksm需要使用madvise显示调用,uksm是默认可以merge的;uksm对zero page的特殊处理,不统计在进程的RES中等。 4,perf 使用perf分析ksm的性能,看看是否有优化的空间:

主要的计算量都在memcmp上,这也变相证明了uksm使用汇编加速zero page的重要性。 5,zero page 对于汇编加速,ksm是不是可以尝试引入呢? 作者做了尝试,在ksm中修改,大概逻辑如下: a,在ksm初始化完毕之前,预先申请一个zero page。 b,把zero page放到stable tree中。 c,对于需要merge的page,先使用汇编加速的逻辑判断是否为zero page。 d,如果是zero page,直接merge,不需要搜索stable tree,节省下所有的memcmp的时间。 e,如果是非zero page,继续搜索stable tree。 测试结果来看,对于zero page的加速很明显,大约提升了ksm的能力的50%左右的样子。对于非zero的情况,有大约10%的性能损失。 6,soft lockup 在Linux上,每个cpu都会启动一个优先级139的内核线程watchdog:

这个线程会周期性的刷新percpu的一个变量----watchdog_touch_ts,默认情况下,这个变量22S没有刷新,就会触发kernel的一个BUG(dmesg中会看到大概内容是BUG: soft lockup - CPU#%d stuck for %us! [%s:%d]\n),换句话说,如果watchdog线程22S没有被调度到,就会触发。 在上面的例子中,我们修改了ksm的每个loop中进行处理的page数量。如果数量很大,足够让ksmd(处理ksm的内核线程)使用CPU达到或者超过22S,那么很可能就触发了这个BUG。 可能有朋友会觉得操作系统是分时的,哪怕watchdog线程优先级低,也不能让他饿死才对。但是这种情况特殊,在编译kernel的时候,如果没有打开编译选项CONFIG_PREEMPT,就会让内核线程不能被抢占。很不幸的时候,作者看了centos7和ubuntu1604,默认都没有CONFIG_PREEMPT。所以这里需要注意一下。一般的发行版中,会有/boot/config-xxxx这个文件,在这里可以确认CONFIG_PREEMPT的开关情况。 后记: 对于ksm的加速,还有一种可能,就是使用汇编加速memcmp。准确来说,就是判断两个page的大小比较关系。希望有朋友可以指点一下。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-04-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 AlwaysGeek 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档