cpu capacity、task_util、cpu_util是如何计算的?
在进程调度中使用到了一些比较关键的参数,用来作为调度、cpu调频、EAS等关键功能的前提。
并且在相关模块中经常交替出现,比较容易混淆,这里单独将这些参数拎出来,做个记录。
cpu_capacity
cpu_capacity是作为cpu算力的量化体现,代表着cpu性能的大小。数字越大,性能越高。
cpu的性能和cpu的运行频率是正相关的,频率越高,性能也越好。所以,在大cluster内cpu的max_capacity比小cluster内的cpu max_capacity更大。
计算公式有2个,一个是cpu最大的capacity:cpu_max_capacity;另一个是当前freq下的cpu capacity。
如下:
获取cpu capacity的代码:
static inline unsigned long capacity_of(int cpu) //cpu_capacity_orig基础上去掉rt、dl以及irq util后的capacity { //计算:(capacity_orig - rt_util - dl_util)*(capacity_orig - irq_util) / capacity_orig return cpu_rq(cpu)->cpu_capacity; }
static inline unsigned long capacity_orig_of(int cpu) //获取当前policy_max_freq下的capacity(可能被thermal影响而缩小) { return cpu_rq(cpu)->cpu_capacity_orig; }
Task util
task util是用来表示一个task大小,它会占用cpu多少算力,或者说是给cpu造成多少负载的体现。task util的监控是通过WALT得到,所以公式中一些参数也与WALT的配置有关。
task util = demand *1024 / window_size ---其中demand为WALT机制中sum_history数组得到的max(latest值,平均值),window_size则是WALT机制中window的大小(默认为20ms)
= (delta / window_size) * (cur_freq / max_freq) * cpu_max_capacity ---delta是task在一个window中运行的真实时间;cur_freq为cpu当前频率;max_freq为cpu最大频率;
特别地,打开了schedtune的boost之后,task util也会进行变化。公式如下:
boosted task util = task_util +(1024 - task_util)* boost_percent ---boost_percent是schedtune中配置的boost百分比
获取task util代码:
static inline unsigned long task_util(struct task_struct *p) { #ifdef CONFIG_SCHED_WALT return p->ravg.demand_scaled; #endif return READ_ONCE(p->se.avg.util_avg); }
CPU util
cpu util则表示当前有多少工作量在该cpu上,是cpu负载的体现。也是通过WALT机制监控得到:cumulative_runnable_avg_scaled。
它是统计了当前一个WALT window中on_rq ==1的所有task util的总和
cpu util = ∑ task_util(x) ---表示所有on_rq的task util总和
∑demand(x) * 1024 / window_size ---∑demand(x) 表示cpu rq中所有runnable的task demand
获取cpu_util的代码:
static inline unsigned long cpu_util(int cpu) { struct cfs_rq *cfs_rq; unsigned int util; #ifdef CONFIG_SCHED_WALT u64 walt_cpu_util = cpu_rq(cpu)->walt_stats.cumulative_runnable_avg_scaled; //cpu负载 return min_t(unsigned long, walt_cpu_util, capacity_orig_of(cpu)); #endif cfs_rq = &cpu_rq(cpu)->cfs; util = READ_ONCE(cfs_rq->avg.util_avg); if (sched_feat(UTIL_EST)) util = max(util, READ_ONCE(cfs_rq->avg.util_est.enqueued)); return min_t(unsigned long, util, capacity_orig_of(cpu)); }
最后提一下schedutil的调频怎么计算的:
1.25 * cpuinfo.max_freq f = ———————————————————————————————— * boosted_util cpu_max_capacity 1.25 * cpuinfo.max_freq = ———————————————————————————————— * [util + (1024 - util) * boost_percent],(boost_percent是schedtune配置的boost值) cpu_max_capacity
其中util计算公式如下:
prev_runnable_sum * (100 + sched_load_boost) util = ———————————————————————————————————————————————————————, (prev_runnable_sum是WALT统计的值,window_size默认20ms) window_size >> 10 * 100
cpuinfo.max_freq现在还有点混淆,之后有空再check清楚到底是不是cpu最大freq?
prev_runnable_sum实际在代码中还会加上一个grp的load。这块属于walt,后续学习schedutil,需要仔细搞清楚。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器