Linux, Go都是O(1)的scheduler

先看这个谈谈调度 - Linux O(1)

linux scheduler的主要操作: search+insert

  1. 查找要执行的任务(search)
  2. 任务执行完时间片后放回或删除(insert/delete)
  3. 切换上下文 // 这个最多只有CPU核数那么多个线程需要切换,所以本身就是O(1)的。

我们可以看到linux使用了2个(bitarray+queue)数据结构, 使得操作1,2都是O(1)的,那么整个调度开销就是O(1)的。
主要过程如下:
假设有如下数据结构体: [140]bit+[140]queue

  1. bitarray是140个bit,代表140个对应的优先级上是否任务需要执行。0表示没有任务,1表示有任务。
  2. 140个queue,存放140个优先级的任务队列,当任务队列变为空,则bit染色为0,不为空则bit染色为1。
  3. search,insert,delete都是bitarray的O(1)+queue的O(1)来完成的。

所以Linux的调度开销是O(1)的。

同理Go的调度开销主要包含search, insert/delete,上下文切换操作,那么Go的调度开销也是O(1)的。
即随着协程数量的增加,Go的调度开销是基本不变的。

这里的协程数量n就是复杂度分析里提到的问题规模大小。

调度系统设计精要--Linux 的 CPU 调度器设计与演进

该文详细说明了Linux,GO,K8s等近乎全部调度系统的设计和演进。
其中Linux的O(1)调度系统的说明,在数据结构这块有图解,可能更易懂。

原文地址:https://www.cnblogs.com/yudidi/p/12419982.html