CPU调度
背景知识
上下文切换
- 切换CPU的当前任务,从一个进程/线程到另一个
- 保存当前在PCB/TCB中的执行上下文(CPU状态)
- 读取下一个进程/线程的上下文
CPU调度
- 从就绪队列中挑选一个进程/线程作为CPU将要运行的下一个线程/进程
- 调度程序:挑选进程/线程的内核函数(通过一些调度策略)
- 什么时候进行调度
在进程/线程的生命周期中的什么时候进行调度?
从一个状态变为另一个状态发生调度,特别是和运行(running)相关的状态变化,如就绪态到运行态,运行态到就等待状态,运行态到退出态都会触发调度
内核运行调度程序的条件(满足一条即可)
- 一个进程从运行状态切换到等待状态
- 一个进程被终结了
不可抢占调度
- 调度程序必须等待事件/进程结束,早期OS。
可以抢占:现在多为可以抢占的进程,OS决定在何时打断进程
- 调度程序在中断被响应后执行
- 当前进程从运行切换到就绪,或者一个进程从等待切换到就绪
- 当前运行的进程可以被换出。
抢占和非抢占可分为用户级进程抢占和内核级进程抢占。(早起的OS不支持用户态进程抢占,windows NT之前)。
内核态抢占:当用户进程执行系统调用,在内核中不会导致该进程处于等待状态,这时,当系统调用返回时,则一定会返回到发起这个系统调用的进程,所以内核中不会切换,抢占。只要进程在系统调用时不存在从运行态到阻塞态的变化,OS可以确保返回正常。 如果在内核中也允许这种抢占,正在执行的系统调用由于特殊事件的产生,需要让当前内核完成一次切换,切换到另一个优先级更高的进程执行,则系统调用返回时会切换到另一进程执行。(linux,现在的windows支持内核级抢占)
调度原则
执行模型:进程在CPU计算和I/O操作间交替
每次调度决定在下一个CPU计算时将哪个工作交给CPU
在时间片机制下,进程可能在结束当前CPU计算前被迫放弃CPU
比较调度算法的评价指标
CPU使用率:CPU处于忙状态的时间百分比
吞吐量:单位时间内完成的进程数量
周转时间:一个进程从初始化到结束包括(所有等待时间)所花费的时间,周转时间=等待时间+服务时间
等待时间:进程在就绪队列中的总时间,进程从就绪态到运行态的时间。
响应时间:一个请求被提交到第一次响应所花费的总时间
吞吐量与延迟
人们通常希望“更快”的服务
什么是更快
传输文件时的高带宽,调度算法的高吞吐量
玩游戏时的低延迟,调度算法的低响应延迟
这两个因素是独立的
与水管的类比:
低延迟:喝水的时候想要一打开水龙头水就流出来
高带宽:给游泳池充水时希望从水龙头里同时流出大量的水,并且不介意是否存在延迟
处理机调度策略的响应时间目标和吞吐量目标
减少响应时间:及时处理用户的输入请求,尽快将输出反馈给用户
减少平均响应时间的波动:在交互系统中,可预测性比高差异低平均更重要
增加吞吐量:减少开销(操作系统开销,上下文切换),系统资源的高效利用(CPU,I/O设备)
减少等待时间:减少每个进程的等待时间
以上两点或者四个目标很难同时做到机制(不同场景不同需求):
低延迟调度改善了用户的交互体验:如果移动鼠标时,屏幕中的光标没动,用户可能会重启电脑
操作系统需要保证吞吐量不受用户交互的影响:操作系统必须不时进行调度,即使存在许多交互任务
响应时间是操作系统的计算延迟
吞吐量是操作系统的计算带宽
处理机调度的公平性目标
- 公平的定义:保证每个进程占用相同的CPU时间,保证每个进程都等待时间的相同
- 公平通常会增加平均等待时间
调度算法
通用OS调度算法
先来先服务算法(First Come First Served,FCFS)
依据进程进入就绪状态的先后顺序排列,进程进入等待或结束状态时,就绪队列中的下一个进程占用CPU
FCFS算法的周转时间
示例:3个进程,计算时间分别为12,3,3
优点:简单
缺点:
- 平均等待时间波动大
- 花费时间少的任务可能排在花费时间长的任务后面
- 可能导致CPU和I/O之间的重叠处理,没考虑抢占,CPU密集的进程导致I/O闲置时,I/O密集型进程也在等待
短进程优先算法(shortest process next,SPN)
选择就绪队列中执行时间最短进程占用CPU进入运行状态
就绪队列按预期的执行时间来排序
- SPN算法的可抢占改进就是最短剩余时间优先算法(shortest remaining time,SRT)
短进程优先算法具有最优平均周转时间(c表示进程的执行时间)
连续的短进程流会使长进程无法获得CPU资源,使长任务饥饿
- 短任务可用时的任何长任务的CPU时间都会增加平均等待时间
需要预知未来(进程执行时间多少)
- 如何预估下一个CPU计算的持续时间
简单的解决办法:询问用户,用户欺骗就杀死相应进程,用户不知道怎么办?
用历史的执行时间来预估未来的执行时间
渐进的模拟,接近实际时间
最高响应比优先算法(Highest Response Ratio Next,HRRN)
选择就绪队列中响应比R值最高的进程
R=(w+s)/s
w: 等待时间(waiting time)
s: 执行时间(service time)(也需要预估)
在短进程优先算法(SPN)的基础上改进
不可抢占
关注进程的等待时间
防止无限期推迟
优点:防止无限期延迟即进程饥饿 ,交互性、响应性更好
缺点:目前该算法不可抢占,对抢占性的支持不够,也需要预估执行时间
轮循算法(RR, Round-Robin)
- 在叫作量子(或时间切片)的离散单元中分配处理器
- 时间片结束时切换到下一个准备好的进程
时间片为20的RR算法示例
时间切片来轮流执行,强调了公平,平均等待时间较长
RR算法开销:额外的上下文切换
时间片太大:等待时间过长,极限情况退化成FCFS
时间片太小:反应迅速,但产生大量上下文切换,大量上下文切换开销影响到系统吞吐量
时间片长度选择目标:选择一个合适的时间片长度,经验规则:维持上下文切换开销处于1%以内
多级队列调度算法(Multilevel Queues,MQ)
- 就绪队列被划分成多个独立的子队列:eg 前台(交互),后台(批处理)
- 每个队列拥有自己的调度策略:eg 前台(RR),后台(FCFS)
- 调度必须在队列间进行
固定优先级:先处理前台,然后处理后台,可能导致饥饿
时间接片:每个队列都得到一个确定的能够调度其进程的CPU总时间,如:80%CPU时间用于前台,20%CPU时间用于后台
问题:不同优先级进程在一开始就划分好了级别,在进程动态执行过程中有可能会变化,如在某一阶段可能侧重交互性,在某阶段可能要做大量计算处理,能否动态调整进程在队列中的级别?
多级反馈队列算法(multilevel Feedback Queues ,MLFQ)
进程可在不同队列间移动
N级优先级 ,优先级调度在所有队列中,每个级别内部RR轮循
时间片大小随优先级级别增加而增加
如进程在当前的时间片没有完成,则降到下一个优先级
优点:CPU密集型进程的优先级下降很快,I/O密集型进程停留在高优先级
公平共享调度算法(FSS,Fair Share Scheduling)
FSS控制用户对系统资源的访问
一些用户组比其他用户组更重要
保证不重要的组无法垄断资源
未使用的资源按每个组分配的资源的比例分配
没有达到资源使用率目标的组获得更高的优先级
评价调度方法:
- 确定性建模,对确定的工作量计算每个算法的表现
- 队列模型:用来处理随机工作负载的数学方法
- 实现/模拟:建立一个允许算法运行实际数据的系统,最灵活,具有一般性
先来先服务算法(FCFS):不公平,平均等待时间较差
短进程优先算法(SPN/SRT):不公平,平均周转时间最小;需要精确预测计算时间;可能导致饥饿
最高响应比优先算法(HRRN):基于SPN调度,不可抢占
轮循(RR):公平,但是平均等待时间较差
多级反馈队列(MLFQ):多种算法的集成
公平共享调度(FSS):公平是第一要素
实时系统调度算法
实时调度(real-time) :
- 实时操作系统的定义:正确性依赖于其时间和功能两方面的操作系统
- 实时操作系统的性能指标:1.时间约束的及时性(deadlines) 2,速度和平均性能相对不重要
- 实时操作系统的特性:时间约束的可预测性
- 实时操作系统分类:
强实时操作系统:要求在指定的时间内必须完成重要的任务
弱实时操作系统:重要进程有高优先级,要求尽量但非必须完成
实时任务:
任务(工作单元)
一次计算,一次文件读取,一次信息传递等等
任务属性:完成任务所需要的资源,定时参数
例子:
软时限和硬时限
硬时限(Harddeadline)错过任务时限会导致灾难性或非常严重的后果
必须验证,在最坏情况下能够满足时限
软时限(Soft deadline)
- 理想情况下,时限应该被最大满足。如果有时限没有被满足,那么久相应的降低要求
尽力保证满足任务时限
可调度表示一个实时操作系统能够满足任务时限要求
需要确定实时任务的执行顺序
静态优先级调度(任务执行之前,优先级已经确定)
动态优先级调度(任务的优先级在变化)
速率单调调度算法(RM, Rate Monotonic)
最佳静态优先级调度
通过周期安排优先级
周期越短优先级越高
执行周期最短的任务
最早截止时间优先算法 (EDF, Earliest Deadline First)
- 最佳的动态优先级调度
- 截止时间越早优先级越高
执行截止时间最早的任务
多CPU调度算法
多处理器调度
多处理器调度更加复杂
- 多个相同的单处理器组成一个多处理器
- 优点:负载共享
对称多处理器(SMP, Symmetric multiprocessing)调度
每个处理器运行自己的调度程序
调度程序对共享资源的访问需要进行同步
对称多处理器的进程分配
静态进程分配
进程从开始到结束都被分配到一个固定的处理机上执行
每个处理机有自己的就绪队列
调度开销小
各处理机可能忙闲不均
动态进程分配
进程在执行中可分配到任意空闲处理机执行
所有处理机共享一个公共的就绪队列
调度开销大
各处理机的负载是均衡的
优先级翻转
- 可发生在任何基于优先级的可抢占的调度机制中,
- 当系统内的环境强制高优先级任务要等待低优先级任务时发生
- 优先级反转的持续时间取决于其他不相关任务的不可预测的行为
反转原因:T3先执行,到t2时访问共享资源,t3时T1抢占,开始执行T1,某时刻需要访问已经被T3占用的共享资源,但该资源还没有释放,所以不能继续T1开始等待,T3继续执行,t5时T2又抢占执行,此时T1受制于T2的执行时间,因为T1必须要等T3,导致T1的时间延长了,引起不稳定状态,系统重启。
解决办法:
1.优先级继承:如果有共享资源,低优先级任务继承等于它所占的资源的最高优先级任务的优先级,当阻塞发生时资源的拥有者的优先级会自动提升,使中间优先级的不能抢占。
2.优先级天花板:资源的优先级=所有可以锁定该资源的任务中优先级最高的那个任务的优先级。
除非优先级高于系统中所有被锁定的资源的优先级上限,否则任务在尝试执行临界区的时候会被阻塞。
持有最高优先级上限信号量锁的任务,会继承被该锁阻塞的任务的优先级