openEuler21.09中的负载均衡算法优化
1. 参考文档
根据openEuler官网上的介绍,其内核对进程调度的负载均衡做了算法优化,来提升系统性能。我们就来看看代码到底优化了什么。
注:下面所涉及的修改不一定都是huawei提交的,有些是从Linux主线上游拉下来的。根据openEuler内核源码看,应该是基于Linux5.10版本。
2. 代码分析
openEuler进程调度优化主要点:优化进程负载均衡算法,减少负载均衡过程中的开销,提升性能;通过对比分析代码,主要分几下个点:
2.1 sched_slice()函数
1)nr_running是个粗略估算,当考虑cgroups时,就明显有缺陷了,需要用h_nr_running来反映组调度中的队列数量;
2)cgroups计算slice容易引起over-scheduling,所以需要比较下slice和sched_min_granularity的值;

(图左边是openEuler内核,右边是Linux5.10内核)
2.2 adjust_numa_imbalance()函数
新增入参dst_weight,该修改目的是允许在node节点之间出现一点浮动的不均衡。
当前,Linux系统中仅当目标节点完全空闲时才允许体现不平衡。 这能解决了一类基本问题,但有点过于谨慎。本次修改重新审视了 NUMA 节点可能不平衡直到 25% 的 CPU 被占用的可能性。 25% 是简要估算的(HT模式下,它是内核的50%)。 在较高的利用率下,平衡应继续正常进行,并保持平衡,直到调度程序域完全繁忙或过度使用。
不过这也不是全场景绝对优化的,在某些测试场景下,该优化并不能体现出优势。需要具体情况具体分析。


(图左边是openEuler内核,右边是Linux5.10内核)
2.3 避免不必要的imbalance计算
该优化操作是在唤醒进程的慢速路径中。
在find_idlest_group()函数中,只有当group是overloaded或者fully busy状态下,才需要计算imbalance值。

2.4 find_idlest_group()函数
该操作是在唤醒进程的慢速路径中。
原本是如果当前group有闲置算力,是在有idle的cpu情况下,才返回NULL,就是返回不必要查找idlest group。欧拉改为了只要当前group中25%以下占用,就认为还是idle的,不需要spill over任务到另一个node,也就是允许一定的不均衡存在(可能其他group有空闲cpu,当前group不是全idle的cpu,但任务占有率在25%以下)。我认为这样应该是减少了不必要的负载均衡迁移过程。

2.5 select_idle_core()函数
该操作是在唤醒进程的快速路径中。
原本函数select_idle_sibling()中会调用select_idle_core()以及select_idle_cpu(),这两个函数会for循环,遍历同一个cpumask列表。这是一定的资源浪费。这两个函数是从上向下遍历不同层级调度域的,比如select_idle_core()遍历SMT层级,select_idle_cpu()遍历MC层级,但其实都是遍历的同一个cpumask列表。如何改进:将select_idle_core()放到select_idle_cpu()里面去做。

当select_idle_cpu()在根据LLC域遍历查找空闲cpu时,也同时去执行select_idle_core()的遍历,这样要做的就是在遍历查找idle core的时候记住遇到的每个non-idle cpu(我的理解是只有非空闲的才需要下一层级也就是select_idle_core()再去遍历查找空闲cpu,否则就已经找到空闲的cpu了,所以这里是记住non-idle cpu),这样总共就只需要对整个cpumask列表遍历一次。



而在5.9.10的内核中,会执行更多的查找idle cpu操作,无疑这是低效率的:

更多推荐
所有评论(0)