基於androidq的code來看內核調度
1、nice值
/*
* Nice levels are multiplicative, with a gentle 10% change for every
* nice level changed. I.e. when a CPU-bound task goes from nice 0 to
* nice 1, it will get ~10% less CPU time than another CPU-bound task
* that remained on nice 0.
* 所以nice值越大,task佔用的cpu的時間越短
*
* The "10% effect" is relative and cumulative: from _any_ nice level,
* if you go up 1 level, it's -10% CPU usage, if you go down 1 level
* it's +10% CPU usage. (to achieve that we use a multiplier of 1.25.
* If a task goes up by ~10% and another task goes down by ~10% then
* the relative distance between them is ~25%.)
* 實際上這裏的值就接近1.25倍的關係
*/
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,
};
/*
* Inverse (2^32/x) values of the sched_prio_to_weight[] array, precalculated.(預先計算)
*
* In cases where the weight does not change often, we can use the
* precalculated inverse(逆) to speed up arithmetics(算術) by turning divisions
* into multiplications(乘法):
*/
const u32 sched_prio_to_wmult[40] = {
/* -20 */ 48388, 59856, 76040, 92818, 118348,
/* -15 */ 147320, 184698, 229616, 287308, 360437,
/* -10 */ 449829, 563644, 704093, 875809, 1099582,
/* -5 */ 1376151, 1717300, 2157191, 2708050, 3363326,
/* 0 */ 4194304, 5237765, 6557202, 8165337, 10153587,
/* 5 */ 12820798, 15790321, 19976592, 24970740, 31350126,
/* 10 */ 39045157, 49367440, 61356676, 76695844, 95443717,
/* 15 */ 119304647, 148102320, 186737708, 238609294, 286331153,
};
2、set_load_weight
static_prio:靜態優先級是和nice關聯的一個值
靜態優先級不會隨時間改變,內核不會主動修改它,只能通過系統調用 nice 去修改 static_prio,MAX_RT_PRIO的值是100,static_prio的取值範圍是100~139
int prio = p->static_prio - MAX_RT_PRIO; 剛好找到對應的sched_prio_to_weight中的值,所以static_prio
task處於idle狀態,他的優先級是固定的3,inv_weight也是固定的
/*
* To aid in avoiding the subversion(顛覆) of "niceness" due to uneven(不均勻) distribution(分配)
* of tasks with abnormal(不正常的) "nice" values across CPUs the contribution(貢獻) that
* each task makes to its run queue's load is weighted according to its
* scheduling class and "nice" value. For SCHED_NORMAL tasks this is just a
* scaled version of the new time slice allocation that they receive on time
* slice expiry(到期) etc.
*/
#define WEIGHT_IDLEPRIO 3
#define WMULT_IDLEPRIO 1431655765
/*
* Increase(增加) resolution(解析度) of nice-level calculations for 64-bit architectures.
* The extra resolution improves shares distribution(分配) and load balancing of
* low-weight task groups (eg. nice +19 on an autogroup), deeper taskgroup
* hierarchies(層次結構), especially on larger systems. This is not a user-visible change
* and does not change the user-interface for setting shares/weights.
*
* We increase resolution only if we have enough bits to allow this increased
* resolution (i.e. 64bit). The costs for increasing resolution when 32bit are
* pretty high and the returns do not justify(證明) the increased costs.
*
* Really only required when CONFIG_FAIR_GROUP_SCHED is also set, but to
* increase coverage(覆蓋範圍) and consistency(一致性) always enable it on 64bit platforms.
*/
// 通過dts文件來配置
// CONFIG_64BIT=y
// 在網上查到這個宏定義的是10
// # define SCHED_FIXEDPOINT_SHIFT 10
#ifdef CONFIG_64BIT
# define NICE_0_LOAD_SHIFT (SCHED_FIXEDPOINT_SHIFT + SCHED_FIXEDPOINT_SHIFT)
# define scale_load(w) ((w) << SCHED_FIXEDPOINT_SHIFT)//左移一般是乘以2,高位溢出捨棄
# define scale_load_down(w) ((w) >> SCHED_FIXEDPOINT_SHIFT)
#else
# define NICE_0_LOAD_SHIFT (SCHED_FIXEDPOINT_SHIFT)
# define scale_load(w) (w)
# define scale_load_down(w) (w)
#endif
所以64位和32位系統是相同的nice值,對應kernel中的weight值是不一樣的
static void set_load_weight(struct task_struct *p)
{
// MAX_RT_PRIO 是100
int prio = p->static_prio - MAX_RT_PRIO;
struct load_weight *load = &p->se.load;
/*
* SCHED_IDLE tasks get minimal weight:
*/
if (idle_policy(p->policy)) {
load->weight = scale_load(WEIGHT_IDLEPRIO);
load->inv_weight = WMULT_IDLEPRIO;
return;
}
load->weight = scale_load(sched_prio_to_weight[prio]);
load->inv_weight = sched_prio_to_wmult[prio];
}