共计 4229 个字符,预计需要花费 11 分钟才能阅读完成。
简介:Linux 内核社区经常以跑分软件得分,来评估一个优化补丁的价值。让软件跑高分,就是实力的体现!
一、背景:性能之战
“不服跑个分”曾经沦为手机行业的调侃用语,然而实话实说,在操作系统畛域“跑分”的确是最重要的评估形式之一。比方 Linux 内核社区经常以跑分软件得分,来评估一个优化补丁的价值。甚至还有 phoronix 这样专一于 Linux 跑分的媒体。而且明天我还想说一点,让软件跑分高,这是实力的体现,是建设在对内核的深刻理解根底上的。本文的故事就源于一次日常的性能优化剖析。咱们在评估自动化性能调优软件 tuned 的时候,发现它在服务器场景,对 Linux 内核调度器相干的参数做了一些渺小的批改,然而这些批改却很大水平改善了 hackbench 这款跑分软件的性能。是不是很有意思?让咱们一起来一探到底。
本文将从几个方面开展,并重点介绍黑体字局部:
- 相干常识简介
- hackbench 工作模式简介
- hackbench 性能受损之源
- 双参数优化
- 思考与拓展
二、相干常识简介
2.1 CFS 调度器
Linux 中大部分(能够粗略认为是实时工作之外的所有)线程 / 过程,都由一个叫 CFS(齐全偏心调度器)的调度器进行调度,它是 Linux 最外围的组件之一。(在 Linux 中,线程和过程只有细微差别,下文对立用过程表述)
CFS 的外围是红黑树,用于管理系统中过程的运行工夫,作为抉择下一个将要运行的过程的根据。此外,它还反对优先级、组调度(基于咱们熟知的 cgroup 实现)、限流等性能,满足各种高级需要。CFS 的具体介绍。
2.2 hackbench
hackbench 是一个针对 Linux 内核调度器的压力测试工具,它的次要工作是创立指定数量的调度实体对(线程 / 过程),并让它们通过 sockets/pipe 进行数据传输,最初统计整个运行过程的工夫开销。
2.3 CFS 调度器参数
本文重点关注以下两个参数,这两个参数也是影响 hackbench 跑分性能的重要因素。系统管理员能够应用 sysctl 命令来进行设置。
最小粒度工夫:kernel.sched_min_granularity_ns
通过批改 kernel.sched_min_granularity_ns,能够影响 CFS 调度周期(sched period)的工夫长短。例如:设置 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_ns
kernel.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 工作模式分为 process mode 和 thread mode,次要区别就是以创立 process 还是 thread 为根底来进行测试,上面以 thread 来进行介绍。
- hackbench 会创立若干线程(偶数),均分为两类线程:sender 和 receiver
- 并将其划分为 n 个 group,每个 group 蕴含 m 对 sender 和 receiver。
- 每个 sender 的工作就是给其所在 group 的所有 receiver 轮流发送 loop 次大小为 datasize 的数据包
- receiver 则只负责接管数据包即可。
- 同一个 group 中的 sender 和 receiver 有两种形式进行通信:pipe 和 local socket(一次测试中只能都是 pipe 或者 socket),不同 group 之间的线程没有交互关系。
通过下面 hackbench 模型剖析,能够得悉同一个 group 中的 thread/process 次要是 I/O 密集型,不同 group 之间的 thread/process 次要是 CPU 密集型。
图 3: hackbench 工作模式
被动上下文切换:
- 对于 receiver,当 buffer 中没有数据时,receiver 会被阻塞并被动让出 CPU 进入睡眠。
- 对于 sender,如果 buffer 中没有足够空间写入数据时,sender 也会被阻塞且被动让出 CPU。
因而,零碎中 ” 被动上下文切换 ” 是很多的,但同时也存在“被动上下文切换”。后者会受到接下来咱们将要介绍的参数影响。
四、hackbench 性能影响之源
在 hackbench-socket 测试中,tuned 批改了 CFS 的 sched_min_granularity_ns 和 sched_wakeup_granularity_ns 两个参数,导致了性能的显著区别。具体如下:
接下来咱们调整这两个调度参数来进行进一步的深入分析。
五、双参数优化
注:为了简介表白上面会以 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 执行工作的工夫需要可能在缓冲区写入 / 读出足够的数据,因而须要较小的 w 来减少唤醒过程的抢占几率,让对端过程可能更快的响应解决数据,缩小下一轮调度时的“被动上下文切换”。
- 对于区域 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.4 最优双参数(对于 hackbench)
- 从下面两节的剖析可知对于 hackbench 这样带有“被动上下文切换”的场景能够抉择较大的 m(例如:15~20ms)。
- 在 pipe/socket 双向通信的场景中,对端的响应工夫会对影响过程的下一次解决,为了让对端过程可能及时响应能够抉择一个中等大小的 w(例如:6~8ms)来获取较高的性能。
六、思考与扩大
- 在桌面场景中,利用更偏差于交互型,利用的服务质量也更多的体现在利用对于用户操作的响应工夫,因而能够抉择较小的 sched_wakeup_granularity_ns 来进步利用的交互性。
- 在服务器场景中,利用更偏差于计算解决,利用须要更多的运行工夫来进行密集计算,因而能够抉择较大的 sched_min_granularity_ns,然而为了避免单个过程独占 CPU 过久同时也为了可能及时处理客户端申请响应,应该抉择一个中等大小的 sched_wakeup_granularity_ns。
- 在 Linux 原生内核中 m 和 w 的默认参数被设置为适配桌面场景,Anolis OS 的用户,须要依据本人部署的利用的场景,属于桌面型还是服务器型,来抉择内核参数,或者应用 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…
对于作者
何惟禹(百奎),阿里云操作系统团队实习生,北京邮电大学在读研究生。
吴一昊(丁缓),17 年退出阿里云操作系统团队,次要经验有资源隔离、热降级、调度器 SLI 等。
原文链接
本文为阿里云原创内容,未经容许不得转载。