介绍:Linux内核社区经常通过运行软件评分来评估一个优化补丁的价值。让软件跑出高分,就是实力的体现!1、背景:在性能之战中,“跑分对抗不满”已经成为手机界的调侃,但说实话,操作系统领域的“跑分”确实是最重要的评测方式之一.例如,Linux内核社区通常通过运行软件评分来评估优化补丁的价值。甚至还有像phoronix这样专注于Linux基准测试的媒体。而今天我要再说一件事,让软件高跑,这是一种实力的体现,是建立在对内核的深刻理解之上的。这篇文章的故事来源于一个日常的性能优化分析。我们在对调优的自动化性能调优软件进行评估时发现,它对服务器场景下Linux内核调度器相关的参数进行了一些小的修改,但是这些修改极大地提升了hackbench这款基准测试软件的性能。.是不是很有趣?让我们一起来了解一下。本文将从几个方面入手,着重介绍加粗的部分:相关知识介绍、hackbench工作模式介绍、hackbench介绍、性能损害来源、双参数优化思路和扩展所有被认为是的线程/进程实时任务由称为CFS(CompletelyFairScheduler)的调度器进行调度,它是Linux的核心组件之一。(在linux中,线程和进程只有一点点区别,下面统称为进程)CFS的核心是一颗红黑树,用来管理系统中进程的运行时间并作为选择下一个进程运行的依据。此外,它还支持优先级、组调度(基于我们熟知的cgroup实现)、限流等功能,满足各种进阶需求。CFS的详细介绍。2.2hackbenchHackbench是Linux内核调度器的压力测试工具。它的主要工作是创建指定数量的调度实体对(线程/进程),让它们通过sockets/pipe传输数据,最后统计整个运行进程开销的时间。2.3CFSSchedulerParameters本文主要关注以下两个参数,这两个参数也是影响hackbench跑分性能的重要因素。系统管理员可以使用sysctl命令进行设置。最小粒度时间:kernel.sched_min_granularity_ns通过修改kernel.sched_min_granularity_ns,可以影响CFS调度周期(schedperiod)的长度。例如:设置kernel.sched_min_granularity_ns=m,当系统中存在大量可运行进程时,m越大,CFS调度周期越长。如图1所示,每个进程可以在CPU上运行不同的时间长度。sched_min_granularity_ns保证每个进程(具有相同优先级)的最小运行时间。sched_min_granularity_ns越大,表示每个进程一次可以运行的时间越长。图1:sched_min_granularity_ns唤醒抢占粒度示意图:kernel.sched_wakeup_granularity_nskernel.sched_wakeup_granularity_ns保证被重新唤醒的进程不会频繁抢占正在运行的进程。kernel.sched_wakeup_granularity_ns越大,唤醒进程抢占的频率就越低。如图2所示,process-{1,2,3}三个进程被唤醒,因为process-3的运行时间大于curr(运行在CPU上的进程)不能抢占运行,运行时间process-2的小于curr但相差小于sched_wakeup_granularity_ns不能抢占运行,只有process-1可以抢占curr运行,所以sched_wakeup_granularity_ns越小,进程被唤醒后的响应时间越快(越短运行等待时间)。图2:sched_wakeup_granularity_ns示意图三、hackbench工作模式介绍Hackbench工作模式分为进程模式和线程模式。主要区别是创建进程还是线程作为测试的依据。下面以线程作为介绍。Hackbench会创建若干个线程(偶数个),分为两类线程:sender和receiver,分为n组,每组包含m对sender和receiver。每个发送方的任务是将大小为datasize循环次数的数据包依次发送给其组内的所有接收方,接收方只负责接收数据包。同组的sender和receiver通信有两种方式:pipe和localsocket(测试只能用pipe或socket),不同组的线程没有交互关系。通过上面的hackbench模型分析,我们可以知道,同一组内的线程/进程主要是I/O密集型,不同组之间的线程/进程主要是CPU密集型。图3:hackbench工作模式下的主动上下文切换:对于接收端,当buffer中没有数据时,接收端会被阻塞,主动让CPU进入休眠状态。对于发送方来说,如果缓冲区中没有足够的空间写入数据,发送方也会被阻塞,主动让出CPU。因此,系统中有很多“主动上下文切换”,但也有“被动上下文切换”。后者受我们接下来要介绍的参数的影响。4、hackbench性能影响的来源在hackbench-socket测试中,tuned修改了CFS的sched_min_granularity_ns和sched_wakeup_granularity_ns两个参数,导致性能有明显差异。具体如下:接下来,我们调整这两个调度参数,进一步深入分析。5、双参数优化注:为了表达简洁,以下将用m表示kernel.sched_min_granularity_ns,w表示kernel.sched_wakeup_granularity_ns。为了探究两个参数对调度器的影响,我们选择一次固定一个参数,研究另一个参数变化对性能的影响。影响,并使用系统知识来解释这种现象背后的基本原理。5.1固定sched_wakeup_granularity_ns图4:固定w,调整m上图中,我们固定了参数w,根据参数m的变化趋势分为三部分:A区(1ms~4ms),B区(4ms~17ms),C区(17ms~30ms)。在A区,四条曲线均呈现出极快的下行趋势,而在B区,四条曲线处于震荡状态,波动幅度较大,最后在C区,四条曲线趋于平稳。在第二节相关知识中,我们可以知道m影响了进程的运行时间,也意味着它影响了进程的“被动上下文切换”。对于区域A,抢占过于频繁,大部分抢占是没有意义的,因为对端没有数据可写/没有缓冲区可用,导致大量冗余的“主动上下文切换”。这时候更大的w可以让sender/receiver有更多的时间写数据/消费数据,减少对端进程无意义的“主动上下文切换”。对于B区,随着m的增加逐渐满足sender/receiver执行任务的时间要求,可以在buffer中写入/读取足够的数据,所以需要更小的w来增加wake-up的抢占概率进程,使得端进程可以更快的响应进程数据,减少下一轮调度中的“主动上下文切换”。对于C区,m已经足够大,几乎不会发生“被动上下文切换”。进程执行任务后会进行“主动上下文切换”,等待对端进程处理。这时,m对性能的影响就很小了。5.2固定sched_min_granularity_ns图5:固定m,调整w上图中,我们固定了参数m,将其分为三个区域:在区域A中,图4的现象也存在,m越大w受影响越小,越小的m性能会随着w的增大而越来越好。在B区,中型m(8ms/12ms)进程中仍有很多“被动上下文切换”,进程已经处理了相当一部分数据,期望对端进程尽快响应处理可能,所以大w会严重影响中等大小m的性能。在C区,图5和图4的表现是一致的,趋于稳定,因为当w过大时,几乎没有唤醒抢占,所以此时w值的简单变化对性能影响不大时间,但太大的w对于适度大的m会导致性能问题(同上原因)。5.3性能趋势概览下面是实验数据的热概览,直观展示m和w的约束关系,供有需要的同学参考和分析。这三个区域将与图4和图5中的略有不同。图6:概述图5.4OptimalDualParameters(forhackbench)从以上两节的分析中,我们可以看到较大的m(例如:15~20ms)可以为hackbench等具有“主动上下文切换”的场景选择。在pipe/socket双向通信的场景下,对端的响应时间会影响到流程的下一步处理。为了让对端进程能够及时响应,可以选择中等大小的w(例如:6-8ms)以获得更高的性能。6.思考与扩展在桌面场景下,应用的交互性更强,应用的服务质量更多体现在应用对用户操作的响应时间上,因此可以选择较小的sched_wakeup_granularity_ns来提高交互性应用程序。在服务器场景下,应用更倾向于计算和处理,应用需要更多的运行时间进行密集计算,因此可以选择更大的sched_min_granularity_ns,但为了防止单个进程独占CPU时间过长,也为了能够及时处理客户端的请求Response,应该选择一个中等大小的sched_wakeup_granularity_ns。在原生的Linux内核中,默认设置了m和w参数以适应桌面场景。AnolisOS用户需要根据自己部署的应用场景选择内核参数,是属于桌面型还是服务器型,或者使用tuned推荐配置。hackbench作为介于桌面和服务器之间的应用程序,也可以作为配置的参考。参考资料phoronix:https://www.phoronix.com/性能自动调优软件tuned:https://developer.aliyun.com/...CFS详细介绍:http://www.wowotech.net/proce。..在原生Linux内核中,默认设置了m和w的参数,以适应桌面场景:https://www.kernel.org/doc/Do...作者何伟宇(白奎),阿里云操作系统团队实习生,北京邮电大学研究生。吴以豪(丁欢),2017年加入阿里云操作系统团队,主要经历了资源隔离、热升级、调度器SLI等。原文链接本文为阿里云原创内容,不得转载没有经过允许。
