EAS-能耗模型

2022-05-13 21:34:59 浏览数 (1)

我们知道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的商。

Debug

如何获得CPU的能耗数据?

https://android.googlesource.com/kernel/common/ /refs/heads/upstream-master/kernel/power/energy_model.c

static int __init em_debug_init(void)

{

/* Create /sys/kernel/debug/energy_model directory */

rootdir =debugfs_create_dir("energy_model", NULL);

return 0;

}

static voidem_debug_create_ps(struct em_perf_state *ps, struct dentry *pd)

{

struct dentry *d;

char name[24];

frequency);"> snprintf(name, sizeof(name), "ps:%lu",ps->frequency);

/* Create per-ps directory */

d = debugfs_create_dir(name, pd);

frequency);"> debugfs_create_ulong("frequency", 0444, d,&ps->frequency);

power);"> debugfs_create_ulong("power", 0444, d,&ps->power);

cost);"> debugfs_create_ulong("cost", 0444, d,&ps->cost);

}

所以在debug的版本下,应该可以看到不同CPU 下的em_cap_state

/sys/kernel/debug/energy_model/pd0/cs:1000000# ls -l

-r--r--r-- 1 root root 01970-01-01 00:00 cost

-r--r--r-- 1 root root 01970-01-01 00:00 frequency

-r--r--r-- 1 root root 01970-01-01 00:00 power

0 人点赞