CFS调度器为了保证优先级高的任务能够获取到较多的运行时间,从而提取出了虚拟运行时间的概念,也即vruntime。
1、权重的概念
为了将任务的优先级考虑到运行时间的计算过程中,CFS调度器又提取出了一个权重的概念,任务的优先级与任务的权重(weight)有一个固定转换关系。
当任务加入到一个cpu的runqueue中时,会将该任务的weight加到cfs_rq的load上面。
2、时间转换函数介绍
物理时间转换为虚拟运行时间的关键函数:
__calc_delta函数是物理时间转换为虚拟运行时间的关键函数,其中delta_exec为运行的物理时间,而weight为任务的权重,lw为与weight比较的权重信息。该函数为了提高精确度做了一些优化,该函数实际执行的动作为:delta_exec * weight / lw.weight。
3、任务预期物理运行时间计算
那么在计算该任务预期运行的物理时间时:为该任务的weight在当前cfs_rq的load中占的比例,与调度周期的乘积。
调度周期的计算方式:
调度周期的计算与当前cpu runqueue中的任务数目有关,如果当前任务的数目不大于sched_nr_latency也就是8,则为固定的调度周期,也就是sysctl_sched_latency。当运行任务数目大于8,则调度周期为nr_running*sysctl_sched_min_granularity。
4、物理时间转化为虚拟时间
将当前任务运行的物理时间转化为虚拟时间时,认为当前NICE值为0的任务,物理时间与虚拟运行时间为1:1的关系,所以在计算任务的虚拟运行时间时,只需要将待计算任务的weight与nice0的weight进行对比计算即可。
所以vruntime = (NICE_0_LOAD/weight)*delta;
5、vruntime保证一致
为什么说在一个调度周期内,每个任务的的vruntime是一致的呢?
(delta_exec * weight / lw.weight)*(NICE_0_LOAD/weight) = delta_exec*(NICE_0_LOAD/ lw.weight)。
而delta_exec为每个调度周期的周期时间。