linux内核调度之SMP负载均衡

SMP调度背景

在多处理器系统上,内核必须考虑好几个额外的问题,以确保良好的调度。

    • CPU负荷必须尽可能公平地在所有处理器上共享。
    • 进程与系统中某些处理器的亲合性(affinity)必须是可设置的。
    • 内核必须是能够将进程从一个CPU迁移到另一个上。

linux SMP调度就是将进程安排/迁移到合适的CPU中去,保持各CPU负载均衡的过程。如下图所示。

SMP调度时机

  • scheduler_tick
  • try_to_wake_up(优先选择在唤醒的CPU上运行)
  • exec系统调用启动一个新进程时

SMP调度分析

CPU拓扑关系构建

系统启动时开始构建CPU拓扑关系。

在ARM中,4核处理器示意图如下所示:

上述4核处理器最后生成的调度域与调度组的拓扑关系图如下图如示:

load_balance

  1. 首先,load_balance()调用find_busiest_queue()来选出最忙的运行队列,在这个队列中具有最多的进程数。这个最忙的运行队列应该至少比当前的队列多出25%的进程数量。如果不存在具备这样条件的队列,find_busiest_queue()函数NULL,同时load_balance()也返回.如果存在,那么将返回这个最忙的运行时队列.
  2. 然后,load_balance()函数从这个最忙的运行时队列中选出将要进行负载平衡的优先级数组(priority array).选取优先级数组原则是,首先考虑过期数组(expired array),因为这个数组中的进程相对来说已经很长时间没有运行了,所以它们极有可能不在处理器缓冲中.如果过期数组(expired priority array)为空,那就只能选择活跃数组(active array).
  3. 下一步,load_balance()找出具有最高优先级(最小的数字)链表,因为把高优先级的进程分发出去比分发低优先级的更重要。
  4. 为了能够找出一个没有运行,可以迁移并且没有被缓冲的进程,函数将分析每一个该队列中的进程.如果有一个进程符合标准,pull_task()函数将把这个进程从最忙的运行时队列迁移到目前正在运行的队列。
  5. 只要这个运行时队列还处于不平衡的状态,函数将重复执行3和4,直到将多余进程从最忙的队列中迁移至目前正在运行的队列.最后,系统又处于平衡状态,当前运行队列解锁,load_balance()返回。

try_to_wake_up

唤醒进程涉及到应该由哪个CPU来运行唤醒进程。当找到一个亲和性的调度域且唤醒的CPU与之前该进程运行的CPU不是同一个CPU,考虑使用当前CPU来唤醒进程。也就是说优先选择wakeup CPU,否则选择pre CPU.

参考资料

<1>.《奔跑吧Linux》
<2>.《深入理解linux架构》

内核资料直通车:Linux内核源码技术学习路线+视频教程代码资料

学习直通车:Linux内核源码/内存调优/文件系统/进程管理/设备驱动/网络协议栈

原文作者:极致Linux内核

原文地址:linux内核调度之SMP负载均衡 - 知乎(版权归原文作者所有,侵权留言联系删除)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值