而在这小小的设备内部,隐藏着无数复杂的机制,其中Linux能量感知调度(Energy Aware Scheduling,简称EAS)便是其中的佼佼者
它不仅关乎手机的性能,更直接关联到我们的使用体验与电池续航
本文将深入探讨Linux EAS的原理,以及它如何在确保性能的同时,最大限度地节省能量
一、Linux EAS的核心概念 1.1 算力(Capacity) 算力是CPU调度中的一个核心概念,它反映了CPU的计算能力
在Android手机中,我们可以通过读取文件节点`/sys/devices/system/cpu/cpu/cpu_capacity`来获得每个CPU的最大算力
这个值是一个规格化的数值,通常将处理器中计算能力最强的CPU的最大算力规格化为1024
CPU的最大计算能力可以通过以下公式计算: CPU的最大计算能力 = capacity-dmips-mhzcpuinfo_max_freq / 1000 其中,`capacity-dmips-mhz`表示该CPU在1mHz频率下运行时可以执行多少个dmips(Dhrystone MIPS),这个值可以从处理器的device tree文件中获取;`cpuinfo_max_freq`表示该CPU支持的最大频率,单位为kHz,因此需要将计算单位kHz转换为mHz,所以除以1000
在CPU算力与频率呈线性关系的处理器中,某一频率点的算力可以通过以下公式计算: CPU某一频率点的算力 =(该CPU某一频点频率 / 该CPU最大频率) 该CPU的最大算力 1.2 Operating Performance Point(OPP) OPP表示每个CPU支持的电压频率对(voltage/frequency tuple)
每个CPU的运行频率点都有一个对应的电压
这个参数对于理解CPU在不同频率下的能耗至关重要
1.3 Power CPU的Energy Model模块提供了相关文件节点,可以用来读取CPU某一频率点的功率
通过读取文件节点`/sys/kernel/debug/energy_model/pd0//power`,我们可以获取小核簇CPU各个频率点的功率(mW)
CPU每个频率点的功率可以通过以下公式计算: P =C V^2 f 其中,C是CPU的电容,可以从处理器的device tree文件中读取“dynamic-power-coefficient”获取;V和f是一个OPP的电压和频率
1.4 能效比 能效比是衡量CPU性能与能耗之间关系的重要指标
CPU每个频率点对应的power/capacity值越低,其能效比越好
一般来说,低频率的能效比优于高频率的能效比;小核簇CPU的能效比优于大核簇CPU的能效比,而大核簇CPU的能效比又优于超大核簇CPU的能效比
然而,小核簇CPU的高频段能效比往往差于大核簇CPU的低频段能效比,大核簇CPU的高频段能效比也差于超大核簇CPU的低频段能效比
在实际应用中,为了让系统更省电而不影响性能,当系统负载不重时,可以让线程更倾向于运行在大核CPU的低频段,避免小核CPU的频率运行在高频率段
而超大核簇CPU由于能效比较差,应尽量避免使用
二、能量感知的线程选核机制 Linux EAS的核心功能在于其能量感知的线程选核机制
它代替传统的CFS(Completely Fair Scheduler)线程唤醒负载均衡代码,利用CPU的Energy Model和PELT/WALT统计到的CPU、线程负载信息,为唤醒线程选择一个最能省电的CPU来运行
2.1 find_energy_efficient_cpu `find_energy_efficient_cpu()`函数负责为唤醒任务找到最节能的目标CPU
它首先在每个性能域中查找空闲算力最大的CPU,并将其作为线程运行的潜在候选CPU
然后,使用Energy Model来确定哪个CPU候选是最节能的
性能域一般对应一个CPU簇
如果线程调度到性能域空闲算力最大的那个CPU上运行,能保证该簇的CPU能运行在需求的最低频率
由于线程迁移的性能代价比较大(如cache失效),只有当选出的最节能CPU比线程当前运行的CPU节约能量大于6%时,线程才会迁移到该CPU运行
2.2 compute_energy `compute_energy()`函数用于预估线程迁移到目标CPU后,性能域的能量消耗
它预估线程迁移后,性能域中利用率最高的CPU的max_util及所有CPU的util之和sum_util,并调用Energy Model提供的API`em_cpu_energy()`来计算线程迁移到性能域时的能量消耗
2.3 em_cpu_energy `em_cpu_energy()`是Energy Model提供的估算性能域所有CPU的能量消耗之和的API
它根据性能域中利用率最高的CPU的利用率max_util来估算性能域CPU需要的最低运行频率,然后在CPU能量模型中找到满足frequency需求的最低性能状态ps
最后,根据性能域中所有CPU的利用率之和sum_util、CPU的算力以及性能状态ps中的cost变量,估算整个性能域的能量消耗
三、EAS与负载均衡 在轻中等CPU利用率的场景中,EAS能够发挥最大的作用
当重载CPU-bound任务在运行时,它们需要尽可能多的CPU算力,此时EAS很难在不严重损害性能的情况下节约能量
为了避免EAS影响性能,一旦某个CPU的利用率超过其算力的80%,整个根域会被标记为“overutilized”,此时EAS会被禁用
而当根域里所有CPU的利用率小于其算力的80%时,负载均衡会被禁用,EAS会覆盖唤醒负载均衡代码
四、EAS的发展与应用 Linux EAS特性主要由Linaro和ARM共同开发,并在Linux Kernel 5.0版本正式发布
它的开发过程经过了漫长的讨论和版本变迁,每个阶段的功能实现首先发生在Android Kernel,然后逐步引入Linux mainline
ARM在2017年发布的DynamlQ架构,实现了总共8 cores的big LITTLE组合CPU架构,Linux Kernel的Schedule和PM也相互融合,随着EAS的到来,支持了非对称多处理器架构
这使得CFS不再是视所有CPU对等的SMP架构特有的调度类
五、结语 Linux EAS作为能量感知调度的杰出代表,不仅为CPU调度带来了新的功能,更在性能与能耗之间找到了完美的平衡点
它依赖于CPU能量模型,为每个任务选择能量最优的CPU,确保了性能影响最小的情况下最大限度地节省能量
随着科技的不断进步,我们对智能手机的需求也在不断升级
而Linux EAS正是为了满足这一需求而生,它让手机在保持高性能的同时,拥有更长的电池续航
这无疑为我们带来了更加便捷、更加智能的使用体验
未来,我们有理由相信,Linux EAS将会继续发展,为我们带来更多的惊喜与可能