我们知道EAS 是基于CPU的能耗模型来进行task的CPU的选择。因此能耗模型至关重要。
对EAS来说需要考虑如下的能耗数据,
· 每个CPU的OPP点的功耗(每个频点的功耗)
· 每个CPU的idle 状态的功耗(C state)
· 每个CPU的从idle 状态到busy 状态的功耗(idle状态的唤醒能源成本)
· 每个cluster的在功耗(L2 cache/LLC 等)
然而手机芯片,基本上只提供了每个CPU在每个OPP的能耗,忽略了其他能耗。因为其他能耗相对贡献比较少,而且如果过多考虑能耗比,会增加task的wakeup时间,增加调度器调频,负载平衡的开销。从而影响系统的性能。
能耗模型
CPU 的能耗模型
在EAS 初始化的版本,这些数据可以从device tree里得到。
然而这种EAS的能耗模型,虽然很全面(CPU/cluser/idle),但是对新的平台来说要获得这些数据不太容易,而且对scheduler来说,计算复杂。从而影响task的wakeup 性能。
当前的EAS能耗模型
能耗模型
其中,
dynamic-power-coefficient:是运行时的能耗系数。
单位是mW/MHz/uV^2。在device tree 里定义。
代码语言:javascript复制V:频点的运行时的电压 单位是uV.
代码语言:javascript复制f: CPU的运行评率,单位是MHZ
某一芯片的power实测值和计算值,从图上可以看出,
两者的差别很少。
能耗模型的架构图
能耗模型的实现
在linux 中提供了能耗模型的框架。大概分为三部分。
§ 最下面的是cpu-hw的实现。包含CPU deriver的实现,能耗相关的是dynamic-power-coefficient。在device tree放在device tree里。还有运行时的OPP的运行CPU freq 和CPU 的电压。这个一般包含在CPU的firmware 中,早期在device tree 中也可以发现相关的值。
§ 然后是Energy Model Framework。是一组通用的框架。定义了相关的API。有些API是CPU deriver 需要实现,有些提供CPU运行时相关的能耗比供thermal和Scheduler(EAS)了解,从而做出决策的。
§ 最上面的便是Thermal 或者EAS来使用相关的API 获取CPU 运行时的能耗数据,做出决策。
Code
代码语言:javascript复制其中最重要的API 是em_register_perf_domain和em_pd_energy
int em_register_perf_domain(cpumask_t *span, unsigned int nr_states,
struct em_data_callback *cb);
在CPU deriver 初始化是进行注册。而em_pd_energy() 是动态获取其 CPU 的能耗信息。
/**
* em_pd_energy() - Estimates the energy consumed by the CPUs of a perf. domain
* @pd : performance domain for which energy has to be estimated
* @max_util : highest utilization among CPUs of the domain
* @sum_util : sum of the utilization of all CPUs in the domain
*
* Return: the sum of the energy consumed by the CPUs of the domain assuming
* a capacity state satisfying the max utilization of the domain.
*/
static inline unsigned long em_pd_energy(struct em_perf_domain *pd,
unsigned long max_util, unsigned long sum_util)
/**
* em_cap_state - Capacity state of a performance domain
* @frequency:The CPU frequency in KHz, for consistency with CPUFreq
* @power: The power consumed by 1 CPU at this level, in milli-watts
* @cost: The cost coefficient associated with this level, used during
* energy calculation. Equal to: power * max_frequency / frequency
*/
struct em_cap_state {
unsigned long frequency;
unsigned long power;
unsigned long cost;
};
代码语言:javascript复制
Cap 计算:
cs->freq ,运行是的CPU freq。
Scale_cpu: 1024
Cpu_max_freq: 当前CPU运行的最大freq
CPU 运行是的功耗:
CS->Power,当前freq的power
Cpu_util, CPU 利用率
CS->cap, CPU 当前freq的能力。
performance domain 运行时的功耗是其cs->cost 与其CPU_util的积,然后与scale_cpu的商。