boosted_task_util实际上包含两个部分,当前task的util加上margin值,margin就是将util的值给他扩大或者缩小一定的倍数
task util = demand *1024 / window_size ---其中demand为WALT机制中sum_history数组得到的max(latest值,平均值),window_size则是WALT机制中window的大小(默认为20ms)
未开启boost = (delta / window_size) * (cur_freq / max_freq) * cpu_max_capacity ---delta是task在一个window中运行的真实时间;cur_freq为cpu当前频率;max_freq为cpu最大频率;
开启boost task util也会进行变化。公式如下:
boosted task util = task_util +(1024 - task_util)* boost_percent ---boost_percent是schedtune中配置的boost百分比
static inline unsigned long task_util(struct task_struct *p) { #ifdef CONFIG_SCHED_WALT if (likely(!walt_disabled && sysctl_sched_use_walt_task_util)) return (p->ravg.demand / (walt_ravg_window >> SCHED_CAPACITY_SHIFT)); #endif return READ_ONCE(p->se.avg.util_avg); }Task utilization 的估算也是依赖walt进行窗口的统计
static inline unsigned long task_util_est(struct task_struct *p) { #ifdef CONFIG_SCHED_WALT if (likely(!walt_disabled && sysctl_sched_use_walt_task_util)) return (p->ravg.demand / (walt_ravg_window >> SCHED_CAPACITY_SHIFT)); #endif return max(task_util(p), _task_util_est(p)); }task util是用来表示一个task大小,它会占用cpu多少算力,或者说是给cpu造成多少负载的体现
static inline unsigned long _task_util_est(struct task_struct *p) { struct util_est ue = READ_ONCE(p->se.avg.util_est);//这里应该是读取一次一个数据结构的宏 return max(ue.ewma, ue.enqueued); }关于struct util_est,可以看https://blog.csdn.net/feifei_csdn/article/details/107106149
struct util_est {
unsigned int enqueued;入队列时估算的task的效力
unsigned int ewma;指数加权动态的平均task的效力
对uti进行成比例的缩放
unsigned int spc_threshold = 100; struct reciprocal_value schedtune_spc_rdiv; static long schedtune_margin(unsigned long signal, long boost) { long long margin = 0; /* * Signal proportional(成比例的) compensation(补偿)(SPC) * * The Boost (B) value is used to compute a Margin (M) which is * proportional to the complement of the original Signal (S): * M = B * (SCHED_CAPACITY_SCALE - S) * The obtained M could be used by the caller to "boost" S. */ if (boost >= 0) { if (signal < spc_threshold) margin = signal * boost; else { margin = SCHED_CAPACITY_SCALE - signal; margin *= boost; } } else margin = -signal * boost; margin = reciprocal_divide(margin, schedtune_spc_rdiv); // reciprocal_divide是计算A/B的优化函数 if (boost < 0) margin *= -1; return margin; }