操作系统-比例份额调度

概述

比例份额(proportional-share)调度程序(又称公平份额(fair-share)调度程序)。比例份额算法基于一个简单的想法:调度程序的最终目标,是确保每个工作获得一定比例的CPU时间,而不是优化周转时间和响应时间。

彩票调度(lottery scheduling)是比例份额调度程序的一个例子。基本思想很简单:每隔一段时间,都会举行一次彩票抽奖,以确定接下来应该运行哪个进程。越是应该频繁运行的进程,越是应该拥有更多地赢得彩票的机会。

彩票调度概念与实现

彩票数表示份额

彩票调度中的彩票数(ticket)代表了进程(或用户或其他)占有某个资源的份额。一个进程拥有的彩票数占总彩票数的百分比,就是它占有资源的份额。

通过不断定时地(比如,每个时间片)抽取彩票(调度程序知道彩票总数,取之间一随机数即可),彩票调度从概率上(但不是确定的) 获得这种份额比例。

例子:

假设有两个进程A和B,A拥有75张彩票,B拥有25张。因此我们希望A占用75%的CPU时间,而B占用25%。

image-20211006161800105

随着这两个工作运行的时间越长,它们得到的 CPU 时间比例就会越接近期望。

image-20211006162644230

彩票机制

  1. 彩票货币(ticket currency) 这种方式允许拥有一组彩票的用户以他们喜欢的某种货币,将彩票分给自己的不同工作。之后操作系统再自动将这种货币兑换为正确的全局彩票。
  2. 彩票转让(ticket transfer) 通过转让,一个进程可以临时将自己的彩票交给另一个进程。这种机制在客户端/服务端交互的场景中尤其有用。
  3. 彩票通胀(ticket inflation)。利用通胀,一个进程可以临时提升或降低自己拥有的彩票数量。通胀可以用于进程之间相互信任的环境。在竞争环境中,进程之间互相不信任,这种机制就没什么意义。

实现

只需要一个不错的随机数生成器来选择中奖彩票和一个记录系统中所有进程的数据结构(一个列表),以及所有彩票的总数就可以实现彩票调度。

假定我们用列表记录进程。

image-20211006162336343
// counter: used to track if we've found the winner yet
int counter = 0;

// winner: use some call to a random number generator to
// get a value, between 0 and the total # of tickets
int winner = getrandom(0, totaltickets);

// current: use this to walk through the list of jobs
node_t *current = head;

// loop until the sum of ticket values is > the winner
while (current) {
  counter = counter + current->tickets;
  if (counter > winner)
    break; // found the winner
  current = current->next;
}
// 'current' is the winner: schedule it... 

如果用数组形式,可以采取前缀和+二分实现。

步长调度

虽然随机方式可以使得调度程序的实现简单(且大致正确),但偶尔并不能产生正确的比例,尤其在工作运行时间很短的情况下。由于这个原因,Waldspurger提出了步长调度(stride scheduling),一个确定性的公平分配算法。

步长调度中的每个工作都有自己的步长,这个值与票数值成反比(取各票数的一个较大公倍数/各票数)。

当需要进行调度时,选择目前拥有最小行程值的进程,并且在运行之后将该进程的行程值增加一个步长。

下面是Waldspurger给出的伪代码:

current = remove_min(queue); // pick client with minimum pass
schedule(current); // use resource for quantum
current->pass += current->stride; // compute next pass using stride
insert(queue, current); // put back into the queue

可以使用优先队列实现之。

与彩票调度的对比

彩票调度有一个步长调度没有的优势——不需要全局状态

假如一个新的进程在步长调度执行过程中加入系统,应该怎么设置它的行程值呢?如果设置成0,新来的进程就独占CPU了。

彩票调度算法不需要对每个进程记录全局状态,只需要用新进程的票数更新全局的总票数就可以了。

因此彩票调度算法能够更合理地处理新加入的进程。

总结

彩票调度和步长调度并没有作为CPU调度程序被广泛使用,原因如下:

  • 不能很好地适合I/O;

  • 最难的票数分配问题并没有确定的解决方式,

比例份额调度程序只有在这些问题可以相对容易解决的领域更有用(例如容易确定份额比例)。例如在虚拟(virtualized)数据中心中,你可能会希望分配1/4的CPU周期给Windows虚拟机,剩余的给Linux系统,比例分配的方式可以更简单高效。

reference

[1] 操作系统导论(ostep)

posted @ 2021-10-06 16:38  zju_cxl  阅读(167)  评论(0编辑  收藏  举报