linux调度器(六)——应用层理解CFS及组调度

来源:互联网 发布:阿里云服务器公网ip 编辑:程序博客网 时间:2024/05/16 10:28

         上面我们介绍了CFS及组调度相关的主要内容,但可能很多人还跟我一样有点云里雾里的,下面我们直接从应用层面上也查看CFS及组调度的效果。首先对于非组调度,决定它们运行时间的唯一因素就是weight,也就是我们知道的nice,我们可以通过renice来重新调整进程的优先级,然后再使用taskset将它们限定在同一个CPU上(CFS只是保证一个CPU的公平,所以你可以看到一个有趣的现象:如指定两个进程的CPU_ALLOWS都有3,4,然后他们的优先级不一样0,3,结果是它们的CPU使用时间是一样的。如果再运行一个0级的进程会怎样?再把它改为5级?——SMP)。
    下面我们看一下组调度,为了便于理解及查看proc信息,我们创建一个包括cpu,cpuset子系统的cgroup(mount –tcgroup –o cpu,cpuset none /cgroup/cpu),然后再在下层创建一个one group,并且它的catcpuset.cpus =3,cat cpuset.cpu_exclusive=1(即该cgroup下的进程只在3号cpu上运行,并且这个cpu是独占的)。我们的例子如下:


图 CFS组调度实例

         我们的目的就是通过这张图算出每个进程(一个死循环的进程)应该使用的CPU资源,并且算出它们对应的cfs_rq的load,以及它们各自的执行时间片,最后再与proc上的信息进行验证。
    组调度的核心思想:每个层级的组按权重去分摊CPU时间给它下面的就绪调度实体(se),每个调度实体获得这个时间后再按照同样的方法递归分摊给它下面的就绪se。
         首先我们通过图可以知道:one这个group下面管理着3个se(其中2个group,即onese->my_q下组织着3个se,而one se->cfs_rq则是指向根’/’的se),依其类推;另外,通过查表prio_to_weight[],可知17444进程对应的load是335(NICE=5, NICE=0 load=1024),则每个进程的se->weight.load:17443(1024);17444(335);17445(1024);17446(1024)。进而可以算出每个group运行队列的权重:[big]cfs_rq->load=[17443]se->weight.load + [17444]se->weight.load = 1024+335 = 1359;[small]cfs_rq->load= [17446]se->weight.load = 1024;[one]cfs_rq->load= [big]se->weight.load + [17445]se->weight.load +[small]se->weight.load = 2048 + 1024 + 512 = 3584;[/]cfs_rq->load= [one]se->weight.load = 1024(这里是因为我们的CPU 3被强占了,其它的进程不会再过来,所以’/’也就只有one一个se)。这样我们就可以算出每个se占用的CPU比例(按100%分配):[big]2048/3584;[17445]1024/3584;[small]512/3584;因为big下面还有两个进程,所以[17443]1024/1359* 2048/3584;[17444]335/1359 * 2048/3584;即最后从左到右的比例分别是:43.1%;14.1%;28.6%;14.3%。我们再从内核角度来看一下上面的组关系:


图 组调度的内部关系

         该图与上图的节点位置是相互对应,另外我们把相应的字段也改成了内核的使用方式。另外根据这些值就可以计算出每个进程的运行时间片(理想)。这里我们不再去计算读者可以按照sched_slice()函数的方法去计算一下,要注意的是对于组调度应该回朔计算到根才能得出该se所应该执行的时间。上面值的结果可以通过/proc/sched_debug来验证。考虑上面我们所说的情况,如果cpu_allows为3,4,然后创建两个进程,它们的cfs_rq load是多少?group的se->load.weight又是多少?【update_cfs_load,update_cfs_shares】
原创粉丝点击