尽量不帅气 发表于 2014-11-17 16:08

如何修改CFS算法为优待IO进程

我的想法是故意地减少IO进程的运行时间:修改代码如下
static inline void
__update_curr(struct cfs_rq *cfs_rq, struct sched_entity *curr,
            unsigned long delta_exec)
{
      unsigned long delta_exec_weighted;
      struct task_struct *my_p;

+       my_p = task_of(curr);

      schedstat_set(curr->exec_max, max((u64)delta_exec, curr->exec_max));
//判断当前进程是不是IO进程
+       if(my_p->ioac.write_bytes > 0){
//是IO进程则减慢vruntime的增长
+            if(count_io > 1){
+                     curr->sum_exec_runtime += delta_exec;
+                      schedstat_add(cfs_rq, exec_clock, delta_exec);
+                     delta_exec_weighted = calc_delta_fair(delta_exec, curr);
+                     curr->vruntime += delta_exec_weighted;
+                     count_io --;
+                      if (entity_is_task(curr)) {//组调度策略由update_curr函数移到这里做一个控制
+                               struct task_struct *curtask = task_of(curr);

+                               cpuacct_charge(curtask, delta_exec);
+                              account_group_exec_runtime(curtask, delta_exec);
+                     }
+               }else{//运行IO进程后不作记账
+                     schedstat_add(cfs_rq, exec_clock, delta_exec);
+                     count_io++;
+               }
+       }else{//不是IO进程则正常运行
+               curr->sum_exec_runtime += delta_exec;
+               schedstat_add(cfs_rq, exec_clock, delta_exec);
+               delta_exec_weighted = calc_delta_fair(delta_exec, curr);
+               curr->vruntime += delta_exec_weighted;
+               if (entity_is_task(curr)) {
+                        struct task_struct *curtask = task_of(curr);

+                     cpuacct_charge(curtask, delta_exec);
+                     account_group_exec_runtime(curtask, delta_exec);
+               }
+       }
      update_min_vruntime(cfs_rq);
}

static void update_curr(struct cfs_rq *cfs_rq)
{
      struct sched_entity *curr = cfs_rq->curr;
      u64 now = rq_of(cfs_rq)->clock;
      unsigned long delta_exec;

      if (unlikely(!curr))
                return;
      /*
         * Get the amount of time the current task was running
         * since the last time we changed load (this cannot
         * overflow on 32 bits):
         */
      delta_exec = (unsigned long)(now - curr->exec_start);

      __update_curr(cfs_rq, curr, delta_exec);
      curr->exec_start = now;
-         if (entity_is_task(curr)) {//移到__update_curr函数中控制运行
-                     struct task_struct *curtask = task_of(curr);

-                        cpuacct_charge(curtask, delta_exec);
-                     account_group_exec_runtime(curtask, delta_exec);
-               }
}


修改后性能并没有提升,请各位大神给点自己的意见,谢谢

humjb_1983 发表于 2014-11-17 16:08

尽量不帅气 发表于 2014-11-18 16:17 static/image/common/back.gif
首先谢谢你的回答,但瓶颈确实是在调度上边,磁盘只用到了57%左右,就是上次我和你说的那个raw设备写的问题 ...
此类问题建议从业务模型方面优化,效果可能更明显,比如绑核,专核用于IO。。

humjb_1983 发表于 2014-11-18 08:47

关键还要看你的测试环境中,CPU是否存在瓶颈。如果瓶颈不在CPU,那优化调度是没意义的。
通常IO的瓶颈都在磁盘上~~

embeddedlwp 发表于 2014-11-18 14:17

CFS对io bound的进程已经有compensation的。仔细读代码。只是不像O(1)那样搞个dynamic prio那么明显。

尽量不帅气 发表于 2014-11-18 16:17

首先谢谢你的回答,但瓶颈确实是在调度上边,磁盘只用到了57%左右,就是上次我和你说的那个raw设备写的问题和2.6.18差远了,后来定位发现是调度器出了问题。回复 2# humjb_1983


   

尽量不帅气 发表于 2014-11-18 16:22

谢谢,我也是刚定位到raw设备IO性能在2.6.28内核中是调度器的问题的,目前刚接触不久;
请问那段代码的实现具体在哪里呢?
还有既然做了优化,为什么调度间隔还有2500us之多,而2.6.18内核中只有1700us左右?上面的数据是我定位IO性能的结果,所用环境都是一样的。回复 3# embeddedlwp


   

humjb_1983 发表于 2014-11-18 16:33

尽量不帅气 发表于 2014-11-18 16:17 static/image/common/back.gif
首先谢谢你的回答,但瓶颈确实是在调度上边,磁盘只用到了57%左右,就是上次我和你说的那个raw设备写的问题 ...
此类问题建议从业务模型方面优化,效果可能更明显,比如绑核,专核用于IO。。

embeddedlwp 发表于 2014-11-18 16:41

回复 5# 尽量不帅气


IO bound的进程一般sleep比较多的。wakeup的时候,vruntime = min_vruntime - sysctl_sched_latency/2(我看的upstream kernel)


   

尽量不帅气 发表于 2014-11-18 17:13

对,是有这个东西,但是它取的是max(se->vruntime,cfs_rq->min_vruntime-sysctl_sched_latency);
这样的话补偿效果并不明显。
回复 8# embeddedlwp


   

尽量不帅气 发表于 2014-11-18 17:17

这样的话,是不是对机器的要求较高,要是在其他机器上CPU不够用,会不会出问题?回复 7# humjb_1983


   
页: [1] 2
查看完整版本: 如何修改CFS算法为优待IO进程