《操作系统导论》第一部分 CPU虚拟化 P4 进程调度(下) MLFQ调度,比例份额调度

C5 调度:多级反馈队列 MLFQ

对于上一篇进程调度的讨论,得到了两类调度方法,一类是优化周转时间的调度方法(SJF,STJF),另一类是优化响应时间的调度方法(RP),但这些调度方式都只能在一个方面有显著的作用,在另一个方面表现不堪人意

在优化周转时间的同时优化响应时间,
接下来介绍MLFQ(Multi-level Feedback Queue)多级反馈队列

多级反馈队列需要解决两方面的问题,首先它要优化周转时间,这通过先执行短的各种来完成,然而操作系统通常不会知道一个任务完成需要多久,而这是SJF,STCF所必需的,其次为了让用户获得良好的交互体验,因此要降低响应时间,但像RP这样的算法周转时间却很差,MLFQ将会用历史经验预测未来,来同时优化周转时间和响应时间

5.1 MLFQ:基本规则

MLFQ中有许多独立的队列,每个队列有不同的优先级,任何时刻,一个工作只能存在于一个队列中,MLFQ总是优先执行高优先级的工作(即高优先级队列中的工作)

每个队列中都可能有多个工作,因此具有相同的优先级,在这种情况下,对这些工作采用轮转调度

所以MLFQ调度策略的关键是如何设置优先级,MLFQ并没有为每个工作指定不变的优先级,而是根据观察到的行为调整它的优先级,如一个工作不断放弃CPU等待来自键盘的输入,这种行为被认为是交互式进程,故MLFQ让它保持高优先级,如果一个工作长时间的占用CPU,MLFQ就降低它的优先级,通过这种方式,MLFQ在进程运行中学习其行为,利用工作的历史来预测它未来的行为

由此有了MLFQ的两条基本规则:
规则1:若A优先级 > B优先级,运行A
规则2:如果A优先级 = B优先级,轮转运行A和B

在这里插入图片描述
对于上述的MLFQ示例图中,A和B处于最高优先级,所以决定轮转运行A和B,但C和D处于低优先级队列是否会一直等待,无法执行?实则不然,工作的优先级将随着时间而进行变化

5.2 尝试1:如何改变优先级(设计一个基本的MLFQ)

我们必须决定,在一个工作的生命周期中,MLFQ如何改变其优先级(将其放置在哪个队列),要做到这一点,需要考虑到:
1,运行时间很短,频繁放弃CPU的交互式工作
2,需要长时间占用CPU,响应时间不重要的CPU密集型工作

对于MLFQ引入3个新规则:
规则3:工作进入系统时,放在最高优先级队列
规则4a:工作用完整个时间片后,降低其优先级,移入下一个队列
规则4b:如果工作在其时间以片内主动释放了CPU,则优先级不变

通过上述的3个规则,来看对于不同的工作MLFQ做如何处理:

(1) 实例1,单个长工作

如果系统中进入一个需要长时间运行的工作,该工作首先进入最高优先级Q2,执行一个时间片后,移入了下一个队列Q1,又执行了一个时间片,移入到了最低优先级队列Q0

在这里插入图片描述

(2) 实例2,来了一个短工作

现在让情况复杂一点,A是一个长时间运行的CPU密集型工作,B是一个运行时间很短的交互式工作,假设A执行了一段时间后B到达,会发生什么?

在这里插入图片描述
对于CPU密集型工作A它处于最低优先级队列,当交互型工作B到达时,它被先放置到最高优先级队列执行,当执行完一个时间片后,被放入下一个较低优先级队列中执行,当B执行完后,A继续执行

通过这种方式,如果不知道工作是长工作还是短工作,那么在开始可将其假设为短工作,并赋予最高优先级,如果确实是短工作,那么很快就会执行完,否则慢慢被移入低优先级队列,被判定为长工作

(3) 示例3,考虑I/O的存在

再考虑工作不仅使用CPU还有I/O操作,根据规则4b,如果进程在时间片用完之前主动放弃了CPU,则保持它的优先级不变,,这条规则的意图很简单,即假设交互型工作中有大量的I/O操作(等待键鼠操作),它会在时间片用完之前放弃CPU,这种情况下,我们并不想降低交互型工作的优先级

在这里插入图片描述
对于CPU密集型工作A将其放置到最低优先队列,对于交互型工作A它与长时间的A竞争CPU,但MLFQ保持B在最高优先级队列,当B等待I/O时,运行A,I/O完成时再回到B,这样就使得交互型程序快速运行

(4) 当前MLFQ的问题

通过上述制定的5条规则,有了基本的MLFQ,长工作之间可以公平地分享CPU,又能给短工作或交互型工作很好的响应时间,但仍然存在着一些严重的缺点

1,存在饥饿问题,如果系统有太多交互型工作,那么长工作永远无法得到CPU服务
2,存在重大的系统漏洞,可能存在某种恶意的应用程序,欺骗调度程序,这个应用程序在每个时间片用完前调用一个无意义的I/O操作,释放CPU,从而导致其永远处于高优先级队列,占用大量的资源
3,一个程序可能在不同时间的表现方式不同,一个计算密集型的程序可能在某段时间表现为一个交互型的进程,目前的方法,它不会享受其它交互型工作的待遇

5.3 尝试2:提升优先级(解决饥饿)

为了解决可能出现的饥饿问题,即让CPU密集型工作取得进展,一个简单的思路就是周期性的提升(boost)所有工作的优先级,最简单的方法可以将所有工作经过一段时间后,放入最高优先级队列,进行轮转

规则5:经过一段时间S,将所有工作重新加入到最高优先级队列

这种方式解决了两个问题:
1,进程不会饿死,CPU密集型工作经过一段时间后从最低优先级队列加入到最高优先级队列,和其它工作轮转执行
2,一个CPU密集型工作变成了交互性工作,调度程序会正确地对待它

在这里插入图片描述
但是S的值应该设置为多少合适?需要丰富的经验才能对S设置合适的值,设置的太高,长工作将会饥饿,设置的太低,交互型工作得不到合适的CPU时间比例

5.4 尝试3:更好的计时方式(解决欺骗调度程序)

接着解决应用程序欺骗调度程序垄断CPU资源的问题,即由于规则4a和4b,导致工作在时间片内释放CPU就会保留优先级,部分恶意程序在每个时间片快结束时,发起I/O以释放CPU欺骗调度程序,垄断CPU资源

这里的解决方案,是为MLFQ每层队列提供更完善的CPU计时方式,调度程序应该记录一个进程在某一层消耗的总时间,而不是在调度时重新计时,只要进程用完了自己的配额时间,无论是一次性用完还是拆分成多次用完,就将它的优先级降低
在这里插入图片描述
有了这样的规则,不论进程的I/O行为如何,都会慢慢的降低其优先级,因而保证公平获取CPU的服务

5.5 MLFQ调优及其它问题

MLFQ应该配置多少队列?MLFQ每一层队列的时间配置份额为多少?为了避免饥饿以及进程行为的改变,多久提升一次进程的优先级?

对于上述的这些问题,只有利用经验和算法模拟,才能得到满意的平衡

高优先级队列通常只有较短的时间片,因而这一层的交互工作可以快速的切换,低优先级队列中更多的是CPU密集型工作,配置更长的时间会取得更好的效果

5.6 MLFQ小结

MLFQ具有多级队列,并利用反馈的信息决定某个工作的优先级,关注进程的表现,然后区别对待

一个合理的MLFQ应遵循的规则:
规则1:如果A优先级>B优先级,则运行A
规则2:如果A优先级=B优先级,则轮转运行A,B
规则3:工作进入系统时,放在最高优先级队列中
规则4:一旦用完了在某一层中的时间配额,就降低其优先级
规则5:经过一段时间S,将所有工作加入到最高优先级中

MLFQ不需要提前了解工作,它通过观察工作的运行来给出对应的优先级,对于短时间运行的交互型工作,获得类似于STCF的作用,保证了周转时间的优秀,对于长时间运行的CPU密集型工作也可以公平的,不断稳步向前运行,类似于RP,轮转调度同步推进它们,许多操作系统都使用MLFQ作为自己的基础调度程序,如BSD UNIX系统及Windows系列

C6 比例份额:彩票调度,步长调度

比例份额调度程序,有时也称为公平份额调度程序,比例份额调度程序的最终目标,是确保每个工作获得一定比例的CPU时间,而不是优化周转时间和响应时间

比例份额调度程序有一个非常优秀的现代例子,即彩票调度,每隔一段时间,都会举行一次彩票抽奖,以确定接下来运行哪个进程,应该频繁运行的进程,就理应该拥有更多的彩票

6.1 基本概念:彩票数表示份额

彩票调度背后的概念:彩票数代表了进程所占某个资源的份额,一个进程拥有的彩票数占总彩票数的百分比,就是它占有资源的份额

看一个例子:进程A和进程B,A有75张彩票,B有25张彩票,因此希望A占用75%的CPU时间,B占用25%的CPU时间
不断定时地从0-99之间抽奖,某进程中奖的概率就是该进程拥有彩票所占总彩票的比例,A中奖率75%,B中奖率25%

在这里插入图片描述
通过不断地抽取彩票来决定运行A或B,调度程序之后加载中奖进程并运行

彩票调度中利用了随机性,这导致了从概率上满足了期望的比例,当这两个工作运行的时间越长,它们得到的CPU时间比例就越接近期望

(1) 利用随机性的好处

彩票调度最精彩的地方就是利用了随机性,当需要做出决定时,采用随机的方式常常是既可靠,又简单的选择,随机方法相对于传统的决策方法,至少有三点优势:
1,随机方法可以避免奇怪的特殊情况
2,随机方法很轻量,几乎不需要记录任何状态
3,随机方法很快

6.2 彩票机制

彩票调度还提供了一些机制,以不同且有效的方式来调度彩票

(1) 彩票货币

这种方式允许拥有一组彩票的用户以它们喜欢的某种货币将彩票分给自己的不同工作,之后操作系统再自动将这种货币兑换成正确的全局彩票

示例:
A用户和B用户都有100张彩票,A有两个工作A1和A2,B只有一个工作Bw,A用自己的货币,给每个工作500张彩票,B用自己的货币给了Bw10张彩票

接着操作系统会将其兑换,将A1和A2各拥有的500张彩票兑换成全局彩票50张,Bw的10张彩票兑换成100张全局彩票,然后抽奖,决定哪个工作运行

在这里插入图片描述

(2) 彩票转让

通过彩票转让,可以让一个进程临时将自己的彩票交给另一个进程,这种机制在服务器/客户端交互的场景中尤其有用

客户端进程向服务器端发送消息,请求其按照自己的需求执行工作,为了加速服务器端程序的执行,客户端将自己的彩票转让给服务器,从而尽可能的加速服务器端执行自己请求的速度,服务器端请求执行结束后,将这部分彩票还给客户端

(3) 彩票通胀

一个进程可以临时提升自己或降低自己的彩票数量,但彩票通胀在竞争环境中,进程间彼此不信任,这种机制就没什么用了,一个贪婪的进程可以一直增加自己的彩票,从而接管机器

但在进程间相互信任的环境下,如果一个进程知道自己需要更多的CPU时间,就可以增加自己的彩票,从而将自己的需求告知给操作系统,这一切不需要与其它进程通信

6.3 彩票调度的实现

彩票调度中最不可思议的就是实现简单,只需要一个不错的随机数生成器来选择中奖彩票和一个记录系统中所有的进程的数据结构,以及彩票总数

下面的例子有A,B,C这3个进程,每个进程有一定数额的彩票:
在这里插入图片描述
在做出调度决策之前,首先从总彩票数400中选择一个随机数(中奖号码),假设选择了300,然后遍历进程链表,用一个简单的计数器来找到中奖者

完成时将会从前向后遍历链表,将每张票的值加到counter上,直到值超过300,即当前的列表元素所对应的进程就是中奖者。上述例子中,先统计A的票,为100不到300,将100加到counter中,继续遍历到B,然后counter增加50,仍然不到300,遍历下一个,接着counter加250,大于300,即选择让进程C运行

6.4 彩票调度的缺陷

现在看一下两个互相竞争工作的完成时间,每个工作都有100张彩票,以及相同的运行时间T,
定义一个简单的不公平指标 U(两个工作完成时间相除),如运行时间T为10s,从0s开始,第一个工作在10s完成,第二个工作在20s完成,U=10/20=0.5,我们希望完美的公平调度可以做到U=1

在这里插入图片描述
由上述的T-U图可以得到,当工作执行时间很短时,平均不公平度很糟糕,只有当工作执行很多时间片时,彩票调度才能得到期望的结果

(1) 如何分配彩票

上面讨论了彩票调度的种种特性和优缺点,但是最关键的是如何为工作分配彩票?

系统的运行严重依赖于彩票的分配,假设用户自己知道如何分配,因此可以给每一个工作相应的彩票,但是具体的分配策略还是没有提及

(2) 短工作下偏离预期

彩票调度利用了随机性,虽然随机性可以使得调度程序的实现简单(且大致正确),但有时不能产生正确的比例,尤其是在工作运行很短的情况下,因为根据概率的随机性只有多次校验才会趋于稳定

6.5 步长调度

为了避免短工作下彩票调度的不稳定,有了步长调度

系统中每个工作都有自己的步长,这个值与彩票数成反比,在上面的示例中A,B,C这3个进程,A有100张,B有50张,C有260张,通过一个大数除以彩票数得到它们的步长,如使用10000,此时A的步长为100,B的步长为200,C的步长为40,每次进程运行后,使用计数器增加它的步长,记录它的总体进展

A,B,C这3个进程的初始行程值为0,最初每个进程都可能被运行,假设运行A,A运行完后,更新它的行程值为步长值即100,然后运行B,运行完后更新其行程值为200,最后运行C,C的行程值变为40,这时算法选择执行最小行程值的进程

成反比
可以看到,C运行了5次,A运行了2次,B1次,正好是进程所拥有的彩票的比例250:100:50,彩票调度算法只能一段时间后,在概率上实现比例,而步长调度算法可以根据彩票份额做到完全符合预期执行

但彩票调度不需要全局状态,假设一个新进程加入了系统,采用步长调度的系统该怎么设置它的行程值,如果设为0,那它就会独占CPU,而在彩票调度系统中,用新进程的票数更新中彩票数即可,彩票调度算法能合理地处理新进程

6.6 份额调度小结

介绍了两种份额调度方式:彩票调度和步长调度,虽然二者都很优秀,但基于一些原因没有广泛被应用于CPU调度程序中,一是因为这二者都不能很好地适应I/O,另一个原因是如何确定彩票数

比例份额调度程序可以用于虚拟数据中心,可能会分配1/4的CPU给Windows虚拟机,剩余的给Linux虚拟机,这种已知如何分配资源的情况下,使用比例分配的方式可以更加高效

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值