10行代码玩转弹性调度的小把戏_dog250 10行代码

Linux的进程调度器是通用的调度器,无论是

O

(

n

)

O(n)

O(n)

O

(

1

)

O(1)

O(1),还是CFS,均是基于统一的指标来对待所有进程的。也就是说,进程甚至无法自主退让。

只要确定了一个进程的优先级,无论是是什么调度算法,该进程的地位总是不会变化,如果能做到下面的策略就好了:

  • 系统中进程多了,就加速退让。
  • 系统中进程少了,就加速抢占。
  • 工人来了,就退让。
  • 经理来了,就抢占。

考虑一个进程A在一个特定的系统中运行,它最多只能用40%的CPU,此时,如果有另外的待运行进程,那么这些进程自然分摊另外60%的CPU,如果再来一个进程A呢?显然,两个进程A的CPU时间均会减少。

能不能保证两个进程A仍然分别使用40%的CPU,然后其它进程分摊剩余20%的CPU呢?很难!

你可能说可以配group啊,但是这必须有一个静态的配置过程,很难动态自适应。

换句话说,Linux的调度器是 非弹性的!

下面的代码展示了一个简单的弹性调度:

#!/usr/local/bin/stap -g

probe kernel.function("__enqueue_entity")
{
    task = _task_of($se)
    pid = @cast(task, "struct task_struct")->pid
    if ($1 == pid) {
        _nr = $cfs_rq->nr_running
        t = $se->vruntime;
        $se->vruntime = t + 3000000*(_nr - 1)
    }
}

意思是指定进程根据系统中负载的数量来退让:

  • 系统负载越高,指定进程占有CPU时间比例越低。
  • 系统负载越低,指定进程占有CPU时间比例越高。

来来来,看效果:
在这里插入图片描述
可以看到:

  • 当只有一个loop的时候,它占用100%的CPU。
  • 当再生一个loop的时候,它几乎和第一个loop平分CPU。
  • 当越来越多的loop运行的时候,第一个loop的CPU份额逐渐降低。
  • 本是同根生,只有第一个loop被弹性了。

嗯,效果还行,但不够平滑。试试二次曲线, or 三次曲线?

$se->vruntime = t + 200*(_nr - 1)*_nr*_nr
// or
// $se->vruntime = t + 20000*(_nr - 1)*_nr

200何来?调一手好参数是必要的。

此外,我这里弹性策略过于单一,其实是可以设计的足够复杂的,比如针对特定进程的特定策略,即便是简单的双斜率直线段,也比我这个OK,是吧,不装逼,不多说。

有人问,如何找到要修改的代码在哪里,只要对Linux内核的执行原理足够熟悉,这并不难,对于手艺人而言,阿基米德,鲁班,庖丁,黄道婆这些人的地位是堪比欧几里得,笛卡尔的。


浙江温州皮鞋湿,下雨进水不会胖!

原文链接: https://blog.csdn.net/dog250/article/details/108281228

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    10行代码玩转弹性调度的小把戏_dog250 10行代码

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/405839

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年4月26日 上午9:27
下一篇 2023年4月26日 上午9:28

相关推荐