linuxカーネルpick_の最適化next_task関数
linux3.3.7のpick_next_task関数のソースコードは次のとおりです.
上のコードに変更するとrq->nr_running=0の場合はidleを直接選択できます.sched_class.pick_next_taskですが、副作用はありますか?
static inline struct task_struct *
pick_next_task(struct rq *rq)
{
const struct sched_class *class;
struct task_struct *p;
/*
* Optimization: we know that if all tasks are in
* the fair class we can call that function directly:
*/
if (likely(rq->nr_running == rq->cfs.h_nr_running)) {
p = fair_sched_class.pick_next_task(rq);
if (likely(p))
return p;
}
for_each_class(class) {
p = class->pick_next_task(rq);
if (p)
return p;
}
BUG(); /* the idle class will always have a runnable task */
}
このコードをよく分析すると、rq->nr_running=0の場合、最適なコードではありません.fair_sched_class.pick_next_taskは2回実行されますstop_sched_class.pick_next_taskおよびrt_sched_class.pick_next_taskは1回ずつ実行され、最後にidle_に実行されます.sched_class.pick_next_task.では、どのように最適化しますか?static inline struct task_struct *
pick_next_task(struct rq *rq)
{
struct task_struct *p;
if(rq->nr_running!=0){
p = stop_sched_class.pick_next_task(rq);
if(p)
return p;
if(rq->rt.rt_nr_running){
p = rt_sched_class.pick_next_task(rq);
if(p)
return p;
}
if(rq->cfs.nr_running){
p = fair_sched_class.pick_next_task(rq);
if(p)
return p;
}
}
else{
p = idle_sched_class.pick_next_task(rq);
if(p)
return p;
}
BUG(); /* the idle class will always have a runnable task */
}
上のコードに変更するとrq->nr_running=0の場合はidleを直接選択できます.sched_class.pick_next_taskですが、副作用はありますか?