滑窗平均的累加计算
权重y按滑窗距离衰减,y^32 = 0.5,也就是经历32个周期将衰减一半的权重,假设本周期值是V,本周期的加权累加值为Vx,则:
一个完整周期是T,给一个基础值1024
其中
Group entity share 的计算
一个entity 的share值指它在计算runqueue上的load时(load_avg)赋予的权重,这个权重用它所在的group的对应cpu上分得的share值来表示(group 在每个cpu上都有一个runqueue,cpu上分得的share用runqueue的share来表示)
runqueue 的 load weight计算,用avg更合适,因为它比实时的weight更稳定,但由于avg的启动比较慢,在极端的场景要保证与用weight来表示的权重一致。例如组内cpu全idle突然启动一个task的场景,这相当于一个只有一个cpu的场景,需要让avg得到的值和单cpu时的值一致,即:
于是用一个近似的形式来拟合:
考虑到Wrq=0时可能有除0问题,分母变为
Entity 与 runqueue 在 load 计算上的区别
block 的 entity 虽然不在 cpu 的 runqueue 上了,但依然在 cfs runqueue 上,只是 load 会以 0 的值对窗口加权。sleep 时间久了,entity 对应的 load avg 会越来越小。
entity 有两种:task,group
task
load sum: 是 runnable 的时间加权和
load avg: 是 load sum × 瞬时权值/ 所有时间窗口加权值
所有时间窗口加权值即前面提过的:
task blocking 时,瞬时值是 0, running 时瞬时值由 nice 值决定,瞬时值与 nice 值关系如下:
cpp
const int sched_prio_to_weight[40] = {
/* -20 */ 88761, 71755, 56483, 46273, 36291,
/* -15 */ 29154, 23254, 18705, 14949, 11916,
/* -10 */ 9548, 7620, 6100, 4904, 3906,
/* -5 */ 3121, 2501, 1991, 1586, 1277,
/* 0 */ 1024, 820, 655, 526, 423,
/* 5 */ 335, 272, 215, 172, 137,
/* 10 */ 110, 87, 70, 56, 45,
/* 15 */ 36, 29, 23, 18, 15,
};
group entity
一个 group entity 对应一个 group 中某个 cpu 上的 run queue
load sum : 有一个任务在 running 状态的时间加权和
load avg : entity对应cfs runqueue分到的share值 * load_sum / 所有时间窗口加权值
cfs runqueue分到的share值是上面提到的:
runqueue
**load sum:**runqueue 中每个 entity 的 load sum * entity 的权重的和
load avg:runqueue 中每个 entity 的 load avg 的和(load avg 已经被加权过了,不用再重新加权)