【内核调度、负载均衡】【boosted

    技术2023-10-24  109

    boosted_task_util实际上包含两个部分,当前task的util加上margin值,margin就是将util的值给他扩大或者缩小一定的倍数

    boosted_task_util

    static inline unsigned long boosted_task_util(struct task_struct *task) { unsigned long util = task_util_est(task);//这里我们假设walt机制是open的 long margin = schedtune_task_margin(task);//margin就是sign除以100 trace_sched_boost_task(task, util, margin);//添加到内核trace log里面 return util + margin; }

    task_util & task_util_est

    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_est

    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的效力

    schedtune_task_margin

    static inline long schedtune_task_margin(struct task_struct *task) { int boost = schedtune_task_boost(task);//返回的应该是我们设置的值-100到100 unsigned long util; long margin; if (boost == 0) return 0; util = task_util_est(task); margin = schedtune_margin(util, boost);//对util进行一定的缩放 return margin; }

    schedtune_margin

    对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; }

     

    Processed: 0.009, SQL: 9