我们看到,实际上nice值的最高优先级和最低优先级的时间比例差距还是很大的,绝不仅仅是例子中的十倍。由此我们也可以推导出每一个nice值级别计算vruntime的公式为:
delta vruntime = delta Time*1024/ load
这个公式的意思是说,在nice值为0的时候(对应的比例值为1024),计算这个进程vruntime的实际增长时间值(delta vruntime)为:CPU占用时间(delta Time)* 1024 / load。在这个公式中load代表当前sched_entity的值,其实就可以理解为需要调度的进程(R状态进程)个数。load越大,那么每个进程所能分到的时间就越少。CPU调度是内核中会频繁进行处理的一个时间,于是上面的delta vruntime的运算会被频繁计算。除法运算会占用更多的cpu时间,所以内核编程中的一个原则就是,尽可能的不用除法。内核中要用除法的地方,基本都用乘法和位移运算来代替,所以上面这个公式就会变成:
delta vruntime = delta time*1024*(2^32/(load *2^32))=(delta time*1024*Inverse(load))>>32
内核中为了方便不同nice值的Inverse(load)的相关计算,对做好了一个跟prio_to_weight数组一一对应的数组,在计算中可以直接拿来使用,减少计算时的CPU消耗:
staticconst u32 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,