l ideal_time = sum_runtime * se.weight/cfs_rq.weight
ideal_time:每个进程应该运行的时间
sum_runtime:运行队列中所有任务运行完一遍的时间
se.weight:当前进程的权重
cfs.weight:整个cfs_rq的总权重
这里se.weight和cfs.weight根据上面讲解我们可以算出,sum_runtime是怎们计算的呢,linux内核中这是个经验值,其经验公式是:
(1) sum_runtime=sysctl_sched_min_granularity * nr_running(if 进程数 > 5)
(2) sum_runtime=sysctl_sched_latency = 20 ms (if 进程数 <= 5)
注:sysctl_sched_min_granularity =4ms
linux内核代码中是通过一个叫vruntime的变量来实现上面的原理的,即:
每一个进程拥有一个vruntime,每次需要调度的时候就选运行队列中拥有最小vruntime的那个进程来运行,vruntime在时钟中断里面被维护,每次时钟中断都要更新当前进程的vruntime,即vruntime以如下公式逐渐增长:
(1) vruntime += delta* NICE_0_LOAD/ se.weight;(if curr.nice!=NICE_0_LOAD)
(2)vruntime += delta; (if curr.nice=NICE_0_LOAD)
在每次更新完vruntime之后,将会进行一次检查,要不要设置调度位TIF_NEED_SCHED,表示要不要被抢占或自动放弃cpu,其实在没有唤醒和CPU之间的进程迁移的时候,只有当前进程主动放弃CPU这种情况,即每个进程都会运行完自己的ideal_time.
即在这里设置抢占位。
通过以上分析,我们基本上已经分析了不开组调度的情况下,进程一般的调度的原理,这里没考虑到唤醒和进程歉意的情况,在后面的文章中会详细的介绍。
至此,我们可能还会有几个疑问:
1 这里只是设置了TIF_NEED_SCHED位,那么谁来检查这个抢占位,来实现进程切换的呢?
这也是在时钟中断里面做的,当时钟中断要返回的时候,会显示的调用schedule()函数,这个函数会检查TIF_NEED_SCHED有没有被置位,来决定是否进行真正的进程切换。
2 还是 A B C这三个进程,如果不考虑唤醒和进程迁移的情况,A的理想的运行时间是3个时间单位,因为只有在
if (delta_exec > ideal_runtime)
resched_task(rq_of(cfs_rq)->curr);
这个时候才设置调度位,那么A运行完这段时间后有没有运行完呢?我们先来仔细分析一下这个公式:
vruntime += delta* NICE_0_LOAD/ se.weight;(if curr.nice!=NICE_0_LOAD)
NICE_0_LOAD是个定值,及系统默认的进程的权值
se,weight是当前进程的权重
delta是当前进程运行的时间
我们可以得出这么个关系:
vruntime与delta成正比,即当前运行时间越长vruntime增长越快
vruntime与se.weight成反比,即权重越大vunruntime增长越慢
现在我们来考虑一种极端的情况:没有唤醒,没有进程迁移,A B C三个进程都是第一次运行
那么系统就会随机从A B C中选一个来运行,因为他们的vruntime第一次是相等的。假设选择B来运行,那么B将运行2个时间单位之后,在某一次时钟中断中发现他的运行时间>它理想运行的时间(runtime>ideal_time),那么将设置TIF_NEED_SCHED位,来进行进程切换;又假设第二次选中了C,那么A运行了稍大于3个时间单位,最后A运行了稍大于1个时间单位。在这种情况下,我们会问,这么运行后A B C有没有运行完啊?(因为我们的理想时间是经验值算出来的),如果没有运行完的话,那下一轮运行又是个什么情况呢?我的理解是经验吧,只有运行的时候才能知道,我们只能感觉上认为应该是对的吧,希望弄明白的同学给我留言!!!
(我想说的是怎么提出一种定量的评价好坏的方法)
3 我们再举一个极端的情况假设有两个用户A,B,注意这里使用户。A用户有1个进程a且a.weight=1;B用户也有1个进程b且b.weight=1000,根据上面的公平理论,我们可以发现B用户可能会一直霸占cpu,在用户更多的情况下,肯能会更糟。为了解决这种问题,CFS引入了组调度,即调度的对象不仅仅限于调度实体,而是可以以用户为调度单位,即A和B位调度单位的话,A B各占50%的CPU。而且只要一个组里的进程被调度,其他的进程也会跟着被调度,但是占用的CPU却至于用户有关。