小众调度器

最近发现了github上有个作者仓库中竟然有多个调度器,分了下源代码。

作者很牛逼。

其他调度器

Baby scheduler

项目地址

作者称,baby scheduler是一个很基本且轻量级但有高性能的CPU调度器,可以用于学习Linux内核调度器;也正是因为其是basic的,所以很多features是没有的。

主要分三种:

Deadline Scheduling (dl) - main
Virtual Run Time Scheduling (vrt)
Round Robin Scheduling (rr)

baby调度器的throughput较高,因为其负载均衡只在一个CPU(CPU0)上进行扫描其他CPUs,然后每次迁移至迁移一个task(每个tick周期)。三种调度器的主要区别就是pick next的选择算法不同(排列顺序本身就不同)。

该调度器中CFS的痕迹很多,基本上就是沿用CFS。主要优化点在于负载均衡

CacULE scheduler

项目地址

该调度器也是一组CFS补丁,主要专注于interactivity score机制,受ULE调度器(freebsd)启发得来。

主要特征:

  1. 每个CPU都有自己的runqueue(这个CFS中也是)
  2. NORMAL runqueue是link-list链表形式的(不是CFS中的红黑树)
  3. RT和其他runqueue和Linux中已有的类似
  4. wake up之后preempt抢占的依据是其interactive score得分更高就可以抢占

cacule中的ineractive score就是源自ULE中,这个我分析过。
可以参考ULE源代码。

CacULE调度器并不是为了替换CFS,主要就是改变了pick next的算法,根据interactive score来选择下一个任务。

TT scheduler

项目地址

task type调度器,也是基于CFS打补丁,不过其将task分类,分了5大类,且这种分类是根据task的行为来实时判断:

#define TT_REALTIME    0
#define TT_INTERACTIVE 1
#define TT_NO_TYPE 2
#define TT_CPU_BOUND   3
#define TT_BATCH   4
  • 那么它是如何判断task type的:

    1. 判断实时进程:burst before sleep is <= 4ms

      #define INTERACTIVE_HRRN   2U
      #define RT_WAIT_DELTA      800000U		//8ms
      #define RT_BURST_DELTA     2000000U		//2ms
       #define RT_BURST_MAX       4000000U	//4ms
      
      if (LEQ(ttn->burst, RT_BURST_MAX) &&
          LEQ(ttn->curr_burst, RT_BURST_MAX))
          return true;
      
    2. 判断cpu_bound类型:

      根据其运行时间占总时间(wait time + vruntime)的百分比,超过80%则是cpu_bound类型

         _hrrn_percent = ttn->vruntime * 100ULL;
         _hrrn_percent /= ttn->wait_time + ttn->vruntime;
      
         return (GEQ(_hrrn_percent, 80ULL));
      
    3. 判断batch类型:

      根据vruntime占总时间百分比,占比50%~80%之间是batch类型

      _hrrn = (ttn->wait_time + ttn->vruntime) / ttn->vruntime;
      
      static inline bool is_batch(struct tt_node *ttn, u64 _hrrn)
      {
         // HRRN > 50%
         return (LES(_hrrn, 2ULL));
      }
      
    4. 判断interactive类型:

      根据vruntime占总时间百分比,小于50%

      _hrrn = (ttn->wait_time + ttn->vruntime) / ttn->vruntime;
      
      static inline bool is_interactive(struct tt_node *ttn, u64 now, u64 _hrrn)
      {
         u64 wait;
      
         if (LES(_hrrn, (u64) INTERACTIVE_HRRN))
             return false;
      
         wait = now - se_of(ttn)->exec_start;
         if (wait && EQ_D(wait, ttn->prev_wait_time, RT_WAIT_DELTA))
             return false;
      
         return true;
      }
      
  • 分出了task type后又是如何干扰调度器的:

    tt scheduler中维护了以个candidate候选队列:但只有realtime和interactive两种类型的任务才能进入候选队列。

    struct global_candidate {
       struct rq *rq;
       struct tt_node *candidate;
       u64 hrrn;
    
       // for update
       raw_spinlock_t lock;
    };
    

    然后再newidle_balance或者nohz_idle_balance的时候,idle空闲cpu就能够从candidate候选队列中拉取任务来执行

    int idle_pull_global_candidate(struct rq *dist_rq);
    

此外:tt scheduler在负载均衡是选择cpu时也是根据rq的nr_running来判断load的,并没有CFS的load_avg那么复杂。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值