CPU调度

CPU调度基础

进程调度

  • 进程切换和调度
    • CPU是共享资源,进程按照一定的策略使用CPU资源
    • 当发生进程切换时,原先的进程不再使用CPU,切换到新的进程使用CPU
    • 进程切换场景
      • 进程主动放弃CPU使用权
      • 进程等待IO、等待资源(例如锁)
      • 内核不让进程使用CPU(例如有更高优先级进程要运行)
    • 进程调度需求
      • 决定使用CPU的进程
      • 非抢占式调度和抢占式调度

非抢占式调度

image-20221020104956853

  • 进程主动放弃CPU使用权(yield)
  • 进程等待I/O,等待资源或特定事件(block
  • 内核调度器直接进行调度(do_scheduler

抢占式调度

image-20221020105039824

为什么要抢占

  • 让进程更加公平的使用CPU资源,避免饥饿
  • 交替使用I/O和计算资源,提升资源的利用率
  • 有紧急任务(高优先级进程)要先执行

基于中断进行抢占式调度

时钟中断或IO中断发生的时候,进行进程切换

  • 硬件中断
    • 由外部事件(外部设备)触发,例如时钟中断,硬盘读写请求完成等
    • 硬件中断产生与当前正在执行的任务无关
  • 软件中断(可编程中断)

按可否屏蔽划分中断

  • 可屏蔽中断
    • 可以关闭/开启中断
  • 不可屏蔽中断
    • 无法恢复的硬件错误等

中断处理的基本流程

  • CPU检查中断条件是否满足
    • 有中断请求
    • CPU允许中断
  • 如果CPU允许中断,则关中断,保证在处理中断的时候不再响应其他中断
  • 保存被中断的线程
  • 判断中断的类型,根据不同的中断类型调用对应的中断处理程序
  • 执行中断处理程序
  • 恢复现场
  • 开中断

I/O中断处理

  • 保存当前进程/线程的上下文
  • 进行I/O,例如将数据从外设拷贝到内核内存中
  • 调用调度器

时钟中断处理

  • 保存当前进程/线程的上下文
  • 更新系统时间,递减进程时间片
  • 调用调度器

调度器

调度器的工作

  • 保存当前进程/线程的上下文
  • 选择下一个待运行的进程/线程
  • 加载相应进程/线程的上下文,并跳转执行

什么时候会触发调度

  • 进程/线程创建
  • 进程/线程退出
  • I/O阻塞或同步阻塞
  • I/O中断
  • 时钟中断

CPU调度算法

调度准则

假设

  • 一个用户运行一个程序,一个程序创建一个线程
  • 程序之间是独立的

常用指标

  • 吞吐率:每秒处理请求数
  • 响应时间(等待时间):从提交一个请求到产生响应所用的时间(交互式系统)
  • 周转时间:从作业提交到作业完成的时间间隔(批处理系统)
  • 公平性:每个程序是否都有执行机会,防止挨饿

批处理和实时交互系统设计目标

  • 保证公平性
  • 最大化CPU资源利用率
  • 最大化吞吐率
  • 最小化周转时间
  • 缩短响应时间
  • 均衡性:满足用户需求且提升计算机系统各部件的利用率

不同类型计算机系统的需求不一样

  • 服务器:看重吞吐率、响应时间和公平性
  • 个人计算机:看重响应时间
  • 工业控制计算机:看重实时性

先到先服务(FCFS)算法

适用于非抢占式调度,适用于批处理系统

核心理念

  • 一个进程一直运行到结束
  • 或一直运行到阻塞
  • 或一直运行到主动放弃CPU

优点:实现简单

缺点

  • 平均周转时间波动较大
    • 短进程可能被排到长进程的后面
  • 可能导致I/O资源利用效率低
    • CPU密集型应用长期占用CPU,导致I/O密集型应用没有机会使用I/O设备
    • 进而导致I/O设备空闲,I/O资源利用率低

最短时间算法

最短时间优先(STCF)算法

适用于非抢占式调度

所有作业同时到达,根据所需时间从小到大依次执行。

最短剩余时间优先(SRTCF)算法

适用于抢占式调度

选择就绪队列中剩余时间最短进程占用CPU并进入运行状态

优点:平均响应时间短

缺点

  • 可能会造成饥饿
  • 由于连续的短进程运行导致长进程始终无法获得CPU资源

时间片轮转(RR)算法

适用于抢占式调度,多用于交互式系统

在时间片结束的时候,调度器按FCFS算法切换到下一个就绪的进程

时间片长度的选择

  • 大时间片
    • 等待时间过长
    • 极端情况下退化为FSFS
  • 小时间片
    • 响应时间块
    • 产生大量上下文切换,影响系统吞吐
  • 经验规则
    • 选择一个合适的时间片,使上下文切换开销处于1%以内

虚拟轮转(VRR)算法

  • 引入辅助队列(FIFO算法)
  • I/O密集型进程进入辅助队列(而不是就绪队列)以备调度
  • 辅助队列比就绪队列有着更高的优先级

多级队列(MLQ)与优先级调度

将就绪队列分为多个独立的子队列,每个队列可有自己的调度算法

例如:将前台任务(交互式)采用RR算法,后台任务(批处理)采用FCFS算法

队列之间

  • 最高优先级优先
    • 固定优先级
    • 先调度高优先级,在调度低优先级
    • 可能导致饥饿
  • 潜在问题:优先级反转
    • 高优先级进程所需资源被低优先级进程占有,需要等待低优先级进程的执行
    • 中优先级进程优先执行,呈现为优先级高于高优先级进程
  • 解决办法:优先级继承
    • 高优先级进程由于等待资源被阻塞时,自动提升低优先级进程的优先级

多级反馈队列(MLFQ)算法

进程可在不同队列间移动的多级队列算法,实现优先级动态调整

特征:

  • 每一级队列分配一个时间片,时间片的大小随着优先级别的增加而减小
  • 进程在当前的时间片没有完成,则降到下一个优先级
  • CPU密集型进程的优先级下降很快,而I/O密集型进程则停留在高优先级
  • 在一定时间周期后,将所有进程的优先级都提升到最高的等级

公平共享调度(FSS)

FSS基于份额控制用户对系统资源的访问

份额管理

  • 按一定的比例在不同用户间分配份额
  • 需要为突发任务预留份额
  • 可以为用户设置份额上限

优先级和份额的区别

  • 优先级表明任务执行的先后,可以优化周转时间、响应时间,但无法确保任务能获得应得的资源比例
  • 份额对应任务使用的资源比例

彩票调度

彩票方法

  • 给每个作业一定数量的彩票(份额)
  • 随机抽取一张中奖彩票,中奖的作业将获得CPU
  • 有较多彩票的作业能获得的调度机会更多,随着调度次数增加,每个作业的彩票数量占比趋近于调度次数占比
  • 为了近似SRTCF,给短作业更多的彩票
  • 为了避免饥饿,给每个作业至少一个彩票

调度算法总结

算法 适用系统 平均响应时间 公平性 潜在问题
FCFS 批处理 可能造成饥饿
STCF 批处理 长进程可能饥饿 需要预测作业执行时间
SRTCF 批处理 长进程可能饥饿 需要预测作业执行时间
RR 交互式 短,I/O进程响应时间较长 公平对待 时间片小会导致吞吐率低
VRR 交互式 对I/O密集型进程友好
MLQ 交互式和批处理 低优先级队列任务 响应时间长 可能造成饥饿 优先级反转
MLFQ 交互式和批处理 兼顾长短作业
彩票算法 交互式和批处理 兼顾长短作业,考虑资源比例

实时调度

两种类型的实时

  • 硬实时:必须满足,否则会产生错误
  • 软实时:大多时候需满足,没有强制性

准入控制

只有当系统能够保证所有进程的实时性的前提下,新的实时进程才能被准入

如果满足以下条件,则作业就是可调度的 \[ \sum\frac{C_i}{T_i}\leq1 \] 其中\(C_i\)为计算时间,\(T_i\)为周期

速率单调调度

假设

  • 每个周期性进程必须在其周期内完成
  • 进程之间没有依赖关系
  • 每个进程在每个周期内需要的CPU时间相同
  • 非周期性进程没有截止时间
  • 进程抢占瞬时发生(没有开销)

基本思想

  • 给每个进程分配一个固定的优先级(出现频率)
    • 例如每50ms运行一次,则优先级是20
  • 运行最高优先级的进程
  • 已经被证明是最优的静态优先级实时调度策略

最早截止时间优先调度(EDF)

假设

  • 当进程运行时,它会提供其需要完成运行的截止时间
  • 不一定是一个周期性的进程

基本思想

  • 根据截止时间对就绪的进程进行排序
  • 运行列表中的第一个进程(最早截止时间优先)
    • 例如P1在30s之前结束,P2在40s之前结束,则P1先运行
  • 当新的进程就绪的时候,并且其截止时间快来临时,它会抢占当前进程