调度:比例份额

操作系统有一个非常有趣的调度程序,比例份额调度(proportional-share),也被称为公平份额调度(fair-share)。比例份额基于一个简单的想法:调度程序的最终目标,就是为了给每一个进程获得一定比例的CPU使用时间,而不考虑周转时间与响应时间。比例份额调度有一个很优秀的例子,由Waldspurger和Weihl提出的彩票调度,顾名思义,就是让进程像彩票一样分配占用时间,哪个进程中奖就能获得更多的占用CPU时间,更越活越的进程,也就得到更多的抽奖机会。

首先,彩票调度中彩票数代表进程占用资源的比例。将整个CPU的所有使用时间定义为100,对所有当前操作系统中的进程进行抽奖,假如有两个进程,那么先抽一次奖,简单理解就可以认为是随机得到一个0-100的随机数,得到的数字就是第一个进程所可以占用CPU的时间份额,第二个进程可占用的份额即为100减去第一个的份额;当有更多的进程数时,只需要进行更多次的抽奖。这个算法最精彩的地方在于其决定性完全来自于随机,只要你的随机数算法够真实,那么得到的结果也就是完全不可预测的。不可预测就可以为开发者带来很多好处,首先是避免了关于算法分配的很多问题,例如时间片轮转的时间片大小问题;然后完全随机的调度只需要记录进程的很少一些状态,因为不需要根据进程的运行时间、优先级、到达时间等等考虑后续的时间片分配,只需要为每个进程记录一个某一时刻属于它的比例份额即可。最后随机方法很快,因为整个调度算法所需要计算的部分只是生成多个随机数,相对于那些为了追求公平而复杂很多的算法,速度上会有很大的提升。

调度:比例份额_第1张图片

上面是我用随机数随机生成的10次比例份额,当然真正的彩票调度算法不可能使用srand这种伪随机。。。。

假设此时操作系统中有两个进程A和B,分别具有的彩票数为75与25,A为0-74,B为75-99,那么按照上面的随机数来看,执行顺序为: A  A  B  A  B  A  B  A  A  A ;

A占用的比例是70%,与他的彩票数份额大致相似,当然这种分配时间越长这个比例也就越接近他的票数份额。

作为一个操作系统的调度算法,如果只是这样那么也没什么值得学习的了,彩票调度自然还有其独有的机制。一种方式是实现彩票货币(ticket currency)的概念。货币自然是用来交易的,也就是说允许进程将自己拥有的彩票,也就是时间份额按照其自有的分配方式分配给自己的各部分工作,然后再由操作系统将交易的份额转换为真正的资源占用时间。另外既然进程中的工作之间可以重分配彩票货币,那么不同进程自然也可以,也就是彩票转让机制(ticket transfer),通过转让,允许一个进程临时将自己的时间份额交给另一个进程。这种机制在C/S交互时极为有用,例如当客户端向服务器发送消息要求其执行某些工作时,为了加速执行,客户端可以将自己的彩票转让给服务器,当服务器执行完客户端所需要的操作后,在将得到的临时彩票返还给客户端,这样可以有效的转化客户端等待时的CPU占用效率。最后,还有彩票通胀机制(ticket inflation),利用通胀,一个进程可以临时提升或降低自己的彩票数量,当然这种行为如果控制不好就会是个极大的问题,因为肯定会有一些恶意进程想要无限的占用CPU。

那么又遇到了与当初时间片轮转算法类似的问题,彩票数该如何分配?

时间片好歹还有时钟中断可以作为基准,那么彩票数该如何分配?很遗憾这个问题没有标准答案,也因为彩票算法并没有在操作系统中被大规模应用,所以我也没法给出一个合适的建议。当然彩票算法没有被大规模应用可能就是因为这个问题没能找到一个令大部分人满意的答案。。。所以这个问题只能你自己去思考了。

另外虽然彩票算法的随机性提供了一个简单的(并且近似正确的)调度器,但它偶尔也不会提供精确的比例,尤其是在短时间内。由于这个原因,Waldspurger提出了步长调度(stride scheduling)。步长调度也很简单,系统中的每一个进程都有一个步长,步长与它所拥有的彩票数量成反比。例如此时拥有三个进程ABC,,分别有100、50和250张彩票。可以用一个很大的数字分别除以他们的票数来获得每个进程的步长。例如,将这个大数设置为10,000,可以得到A、B和C的步长为100、200和40。这个值就是每一个过程的步长,每次进程运行时,会让它的计数器(行程,pass)值增加它的步长,来记录它的总体进展。

例如上面的三个进程从头开始运行,其步长分别为100、200和40,所有这些进程的初始行程为0。因此,假设从0时刻A先开始运行,完成时间片后,将其行程更新为100。然后运行B,它的行程被设置为200。最后运行C,其传递值增加到40。此时,算法将选择最低行程的进程,即C,运行它,更新它的传递到80。然后C将再次运行,因为此时仍然是C具有最低的行程,将其传递到120。于是A将被运行,更新到200,此时A等于B,然后C又将运行两次,更新到200。这时,所有的进程行程都是相等的,就又会开始重复从0开始的进程调度操作,一直无限执行下去。从第一阶段可以看出,C运行了5次,A两次,B一次,刚好与它们的彩票数250,100,和50对应,这表明彩票调度随着时间的推移达到了概率的比例,在每一个调度周期的末尾,步长调度完全正确。

 

最后,想一想为什么彩票调度没有被大规模的应用在操作系统上。一是因为彩票分配算法没有一个令人满意的实现,二是彩票调度对具有I/O的情况还无法很好的适应。所以现在的彩票调度算法只在某些领域被应用,例如虚拟机,具体实现请参阅文章“Memory Resource Management in VMware ESX Server”,了解如何在VMWare ESX服务器中按比例共享内存。

 

 

你可能感兴趣的:(操作系统)