內核調度【一】【nice值】【set_load_weight】

基於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];
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章