抱歉由于工作的繁忙拖更了两个月,我们来接着聊聊IPA
IPA(intelligence power allocator),从名字可以分成两部分,Intelligence是一部分,power allocator是另一部分。
我们这次来先来说说intelligence的部分,这里本质上其实是一个基于闭环控制的系统。
要讲清楚IPA,需要讲清楚的是自动控制原理。如果大家手边还有大学的课本(估计应该没有),大家可以翻开大学的课本来看看闭环控制以及PID算法的定义。
闭环控制是指控制论的一个基本概念。指作为被控的输出量以一定方式返回到作为控制的输入端,并对输入端施加控制影响的一种控制关系。带有反馈信息的系统控制方式。
简而言之,闭环控制是一个与开环控制相对的概念。将反馈信息重新输入至系统的输入端,进而进行控制的方法。IPA智能的一部分即在于此,输入的控制信息是温度,反馈的信息也是温度,由控制输入来调节温度。智能在于省略了中间的关键的功耗信息。传统的温控是通过各种方式来控制功耗进而对温度进行控制。这里直接省去了对中间状态的描述过程,直接由初始的温度映射最终的温度状态,中间的各种功耗以及器件状态信息都被省略了,交由控制系统自动进行调节。
PID是工业控制系统中常用的控制回路反馈控制器。
The PID controller is a closed-loop control system. It feeds the output of the system back to the input of the controller, so that it obtains an accurate or adaptive control. It evaluates the difference between the reference value and the output, and tries to minimize the difference to zero. Therefore, it can avoid various problems with the open loop control system, such as inability to respond to disturbances, and inability to adjust to different systems.
下面是一个简单的PID控制框图,负反馈的控制流程由三部分组成,分别是差分(P)、积分(I)、微分(D)组成。
即误差值,误差值和预定值的差异,往往直接控制于被控制量。
误差在时间上的积分。一个简单的比例系统(即只有差分控制的系统)会在目标值的附近来回变化,这是差分系统的性质决定的,因为系统无法消除这样的误差。积分项的作用是误差的累计,所以加上积分项可以有效消除系统的平均误差值
微分是误差的一阶导数,表示误差的变化率。当误差的变化率较大时,这项影响较大,系统就可以提前(或者以较快的速度)做出响应。需要说明的是在IPA中这项的系数往往是0,微分项没有参与控制
上面的图是按ARM的bigLITTLE架构来讲的,实际的控制流程其实分成几部分:
1. 各个器件(thermal cooling device)根据自己的performance状态计算自己需求的状态。
2. IPA governor收集各个器件的状态信息,同时收集器件的温度Tdie、Tskin等。
3. IPA governor根据器件的状态信息和温度信息,同时根据前刻的状态信息,计算出此时能够赋给各个cooling device的状态信息
4. 各个cooling device得到自己的状态信息,根据governor要求调整自己的状态。
这里开始咱们对着代码来讲吧。看看代码里是怎么对温度进行收集,进而最终转化到器件的状态从而控制温度的。这里咱们主要就以CPU频率来做主要的温控器件了,其他器件同理。
主要的代码路径:
power_allocator.c
cpufreq_cooling.c
关键的结构体:
/**
* struct cpufreq_cooling_device - data for cooling device with cpufreq
* @last_load: load measured by the latest call to cpufreq_get_requested_power()
* @cpufreq_state: integer value representing the current state of cpufreq
* cooling devices.
* @max_level: maximum cooling level. One less than total number of valid
* cpufreq frequencies.
* @em: Reference on the Energy Model of the device
* @cdev: thermal_cooling_device pointer to keep track of the
* registered cooling device.
* @policy: cpufreq policy.
* @idle_time: idle time stats
* @qos_req: PM QoS contraint to apply
*
* This structure is required for keeping information of each registered
* cpufreq_cooling_device.
*/
struct cpufreq_cooling_device {
// CPU的loading,作为CPU频率换算的重要参数
u32 last_load;
// cpu的frequency
unsigned int cpufreq_state;
unsigned int max_level;
// em_perf_domain的结构体,这个是从EAS借过来的结构体,其存储了各个频点对应的power信息,可惜只有动态功耗,不过也避免了咱们再去通过电压、频率和静态功耗系数再计算一遍的困扰
struct em_perf_domain *em;
// cpufreq_policy 存储了cpu cluster相关的各种信息
struct cpufreq_policy *policy;
// SMP仅在多核状态下生效
#ifndef CONFIG_SMP
struct time_in_idle *idle_time;
#endif
// qos链表,最终生效的限频由这里下发,准备之后再写篇文章讲讲QOS(如果不鸽我就写)
struct freq_qos_request qos_req;
};
整体函数的调用链如下,总体来说还是比较清楚的
power_allocator_throttle()
allocate_power()
get_requested_power(cdev, &req_power[i])
cpufreq_get_requested_power()
get_dynamic_power(cpufreq_cdev, freq);
pid_controller(tz, control_temp, max_allocatable_power);
divvy_up_power()
power_actor_set_power(instance->cdev, instance, granted_power[i]);
首先在power_allocator_throttle
中判断是否需要进入温控,如果进入温控,则去调用allocate_power开始收集各个cooling device的performance需求,转化为power,计算状态值并得出最终能够赋给各个器件的power值,最终再下发给各个器件。
最后的代码走读放到最后一章里,我们再花一篇的篇幅来讲讲IPA的工作流程吧