下面是MTK的调度器的演变过程,我们顺着这个过程来学习下历代的调度器在手机系统上的演变过程
1. SMP
随着计算机技术(特别是以芯片为主的硬件技术)的快速发展,CPU 架构逐步从以前的单核时代进阶到如今的多核时代,在多核时代里,多颗 CPU 核心构成了一个小型的“微观世界”。每颗 CPU 各司其职,并与其他 CPU 交互,共同支撑起了一个“物理世界”,这个最常用的时SMP架构,对称多处理器系统,指的是一种多个 CPU 处理器共享资源的电脑硬件架构。对于此时task分配主要是基于linux2.6中的调度策略CFS,SMP是基于该调度策略平均的balance各个core上的负载情况。如下图所
2 big.LITTLE
对于移动端,除了性能,功耗也是一个重要的指标,为了降低功耗,ARM开发了大小核架构处理器,而此时linux内核的负载均衡算法还是基于SMP模型,并未考虑big.LITTLE模型。“big.LITTLE”是ARM 公司在2012年新推出的一种处理器架构。为的是解决处理器性能提升和功耗/发热控制这一对矛盾。
当手机在运行的时候,绝大部分时间只有LITTLE在工作,当运算负载变化的时候,芯片通过DVFS(Dynamic Voltage Frequency Scaling)调整运行频率;当负载继续变高,需要更多的算力时,芯片会将工作切换到big核上继续执行,直到负载下降,重新回到LITTLE。只包含两个调度域,大核调度域和小核调度域,也不考虑这两个调度域之间的负载均衡问题,没有调度组和调度能力的概念,调度域也没有拓扑层次关系。它的主要工作原理是:
- 检测小核调度域,如果有繁重的任务(最重的),就迁移到大核调度域中的空闲CPU上(idle CPU)。
- 检测大核调度域,如果有简单的任务(最轻的),就迁移到小核调度域中的空闲CPU上(idle CPU)。
big.LITTLE架构支持三种使用方式:Cluster Migration, CPU Migration和HMP(Heterogenous Multiple Processing, 也叫 Global Task Scheduling)。
-
在Cluster Migration模式,只能进行簇(cluster)切换,即只能同时使用4核Cortex A7或者A15。这是big.LITTLE最初的模式,Galaxy S4(Exynos 5410)也只能使用这种模式。
-
在CPU Migration模式,内核可以单独切换,但是只能切换到自己对应的内核上。比如CPU0.big(Cortex A7)只能和 CPU0.LITTLE(Cortex A15)互相切换,CPU1.big只能和CPU1.LITTLE切换。这样子,带来了一定的灵活度,但是同一时刻工作的CPU仍然不会超过4颗。
-
linaro开发除了一个HMP调度器用于支持这种架构,它也被用于Android 5.x和android 6.x中,但这种调度器并未被合入内核的基线中,big.LITTLE可以单独管理所有的内核,分配任务。最多可以让8个内核同时工作
同时每个工作域独立控制电压和频率,则可以根据负载、分别控制各个域
3 EAS
异构多处理器(Heterogeneous Multi-Process, HMP)调度器在2015年发布之后没有更新,原来linaro和高通等ARM厂商不满足HMP调度器的设计,又提出了绿色节能调度器。2012年,google工程师Paul Turner针对CF在计算负载的不合理之处提出了称为“Per-entity Load Tracking”的进程负载计算方法,简称为PELT。但是在移动端,特别在手机的应用场景下PELT算法有很多缺陷,其主要表现如下:
- 在手机使用中,经常会产生一些突发的重活(Heaver Task,即负载大的任务),如滑屏或浏览网页,需要能快速识别重活并迅速提高CPU的频率或者将其迁移到计算能力更强大的CPU内核上(大核或者最大频率比较高的核),则可以有效提高手机的流畅性。
- 由于网络延时等原因,导致一个进程睡眠了300ms,然后突然发送或者接受大量王国罗数据包,PELT算法也不能立马识别到它是一个重活
- 但是PELT算法在辨别进程的负载变化上有些迟钝,对于一个突然100%持续运行的进程,需要大约74ms才能达到最大负载的80%,需要大约139ms才能达到最大负载的95%。
- 同时PELT算法使用32ms的衰减,大约213ms才能把之前的负载衰减完,也就是将历史负载清0,这个特性对一些周期性的进程不是很友好,因此有些进程需要存储CPU和频率等信息来提高吞吐,
- 对于睡眠或阻塞的进程,PELT还会继续计算其衰减负载,也就是继续为就绪队列贡献量化负载,但是这些继续贡献的负载对于下一次唤醒其实没有用处,因此会推迟降低CPU频率的速度,从而增加CPU功耗
针对上诉在移动端上的问题,可以使用新的计算进程负载的方式-—窗口辅助负载跟踪(window-Assisted load Tracking WALT)算法,该算法已经被Android社区采纳,并在Android7.x中被采纳,但是linux社区并没有接纳。
在绿色节能调度器的发展过程中,为了把绿色节能调度器合并到linux社区里,绿色节能调度器放弃了WALT算法,而采用linux内核的PELT算法,在Linux5.0内核中,绿色节能调度器大部分代码已经合并到linux社区里。所以 EAS调度器 ,希望对现有的以性能优先的调度策略、调度器、CPUidle和CPUFreq模块的相对独立的现状做出改变,让它们可以紧密工作在一起,从而进一步优化功耗和效率,这个改变叫作Energy Aware Scheduling,简称EAS。EAS调度器的 设计目标 是在保证系统性能的前提下尽可能地降低功耗。