operating systems

CPU调度:

  到目前为止,运行进程的低级机制(例如,上下文切换)应该是清楚的。如果他们不是,那就回一两章,看看这些东西是如何工作的。然而,我们还没有理解OS调度器使用的高级策略。我们现在要做的就是,提出一系列的计划政策(有时被称为学科),那些聪明和勤奋的人多年来一直在发展。调度的起源,事实上,是先于计算机系统的;早期的方法取自于操作管理领域,并应用于计算机。这一事实并不令人惊讶:装配线和许多其他的人类活动也需要调度,其中许多同样的问题也存在,包括对效率的一种类似激光的渴望。

  因此,我们的问题:我们应该如何开发一个基本框架来思考调度策略?关键假设是什么?重要的指标是什么?在最早的计算机系统中使用了什么基本方法!工作负载的假设。
在了解可能的策略的范围之前,首先让我们对系统中运行的流程进行一些简化假设。有时统称为工作负载。确定工作负载是构建策略的关键部分,而且您对工作负载了解得越多,您的策略就会越精确。我们在这里所做的工作量假设大多是不现实的,但这是可以的(目前),因为我们将在我们离开时放松它们,最终发展我们所说的……(戏剧性的停顿)…。
   一个能够全面运行调度纪律。我们将对在系统中运行的过程(有时称为作业)进行如下假设:
1。每一份工作的时间都是一样的。2。所有的工作同时到达。3所示。一旦开始,每一项工作都要完成。4所示。所有作业只使用CPU(即:,他们不执行I/O) 5。每个作业的运行时都是已知的。

我们说过很多这样的假设都是不现实的,但是就像有些动物在奥威尔的动物农场里比其他动物更平等一样,在这一章里有些假设比其他的更不现实。特别是,它可能会使您感到困扰,因为每个作业的运行时都是已知的:这将使调度器无所不知,尽管它可能很好(很可能),但不太可能很快发生。

7.2调度指标

除了做工作量假设之外,我们还需要一件事来让我们能够比较不同的调度策略:调度度量。度规是我们用来衡量某物的东西,而且有许多不同的指标在计划中是有意义的。然而,就目前而言,让我们通过简单的单一指标来简化我们的生活:周转时间工作的周转时间定义为工作完成的时间减去工作到达系统的时间。您应该注意到,周转时间是一个性能指标,这将是本章的主要重点。另一个衡量兴趣的指标是公平,如Jain的公平指数所衡量的(例如)。在日程安排中,表现和公平性常常是不一致的。例如,调度器可以优化性能,但代价是阻止一些作业运行,从而降低公平性。这个难题告诉我们,生活并不总是完美的。

  • 7.3先进先出

们所能实现的最基本的算法是先到先出(FIFO)调度,有时是先到先服务(FCFS)。 FIFO有许多优点:它很简单,因此易于实现。根据我们的假设,它运行得很好。想象一下,在系统中,A、B、C三个工作机会同时到达(Tarrival = 0)。因为FIFO必须先做一些工作,让我们假设他们都是同时到达的。A刚好在B之前, B刚好在C之前到达。假设每个作业运行10秒钟。这些工作的平均周转时间是多少?

从图7.1可以看出,A在10,B在20,C在30。因此,三个工作的平均周转时间是10+20+30 3 = 20。计算周转时间很简单。

现在让我们放松一个假设。特别地,让我们放松假设1,因此不再假设每个作业都运行相同的时间。菲菲现在表现如何?你能构造出什么样的工作量来让FIFO表现不佳?想必你已经算出来了,但以防万一,我们还是算了吧。 举例说明不同长度的作业如何导致麻烦。 FIFO调度机制。特别地,让我们再假设三个工作(A, B,和)。 C),但这次A跑100秒,B和C跑10秒。


正如您在图7.2中所看到的,在B或C之前的100秒内,作业A首先运行,甚至有机会运行。因此,系统的平均周转时间是高的:痛苦的110秒(100+110+120 3 = 110)。

这一问题通常被称为“护航效应”[B+79],在这里,一些相对较短的资源潜在消费者会被排在重量级资源消费者的后面。这个调度场景可能会让您想起在杂货店的一行,你的感觉是什么时候,你看到前面的人有三辆车装满了食物和支票簿;它会存在多久?那么我们应该怎么做呢?我们如何开发一个更好的算法来处理我们在不同时间运行的新工作现实?想想第一;然后继续读下去。

7.4最短工作优先(SJF)。

事实证明,一个非常简单的方法解决了这个问题;事实上,这是一种从运营研究(C54,PV56)中窃取的想法,并应用于计算机系统的工作安排。这种新的调度规则被称为最短作业优先(SJF),名称应该很容易记住,因为它完全描述了策略:它首先运行最短的作业,然后是下一个最短的作业,等等。


让我们以上面的例子为例,但是使用SJF作为我们的调度策略。图7.3显示了运行A、B和c的结果,希望图能清楚地说明为什么SJF在平均周转时间上表现得更好。简单地说,SJF在A之前运行B和C,将平均周转时间从110秒降低到50(10+20+ 1203 = 50),这是两个改进的因素。事实上,考虑到我们对工作的假设同时到达,我们可以证明SJF确实是一个最优的调度算法。然而,您是在一个系统类,而不是理论或操作研究。

先发制人的调度器

在批量计算的旧时代,开发了一些非抢占式调度器。这样的系统将在考虑是否运行新工作之前完成每个任务。实际上所有的现代调度器都是抢占式的,并且非常愿意停止一个进程运行以运行另一个进程。这意味着调度器使用了我们以前学过的机制。特别地,调度器可以执行上下文切换,暂时停止一个正在运行的进程,并恢复(或启动)另一个进程。因此,我们采用了一种很好的方法来调度SJF,但是我们的假设仍然是不现实的。让年代放松。特别地,我们可以设定假设2,现在假设工作可以在任何时间到达,而不是一次性到达。这导致了什么问题!在这里,我们可以用一个例子来说明这个问题。这一次,假设A到达t = 0,并且需要运行100秒,而B和C到达t = 10,每个需要运行10秒。使用纯SJF,我们可以得到图7.4所示的时间表。


从图中可以看出,虽然B和C在A之后不久到达,但是他们仍然被迫等待,直到A完成,从而遭受相同的护航问题。这三个工作的平均周转时间是103.33秒(100+(110 10)+(1203 10))。调度器能做什么?

7.5最短完工时间(STCF)

为了解决这个问题,我们需要放松假设3(工作必须完成),所以让我们这样做。我们还需要调度程序内部的一些机器。正如您可能已经猜到的,考虑到我们之前关于定时器中断和上下文切换的讨论,当B和C到达时,调度器当然可以做其他的事情:它可以抢占job A,并决定运行另一个作业,可能会在以后继续运行。根据我们的定义,SJF是一个非抢占式调度器,因此会受到上述问题的困扰。

幸运的是,有一个调度程序,它可以精确地做到这一点:在SJF中添加优先级,称为最短时间完成优先级(STCF)或抢先的最短作业优先级(PSJF)调度器[CK68]。

任何时候一个新的,STCF调度器确定剩下的工作(包括新工作)中剩下的时间最少,并安排一个。因此,在我们的示例中,STCF将抢占A并运行B和C以完成;只有当他们完成时,剩下的时间才会安排。图7.5显示了一个示例。结果是一个大大提高的平均周转时间:50秒(120 0)+(20 3 10)+(30 10))。和之前一样,考虑到我们的新假设,STCF是最优的;考虑到SJF是最优的,如果所有的工作同时到达,您应该能够看到STCF最优性背后的直觉。

7.6一个新的度量:响应时间

因此,如果我们知道作业长度,而且作业只使用CPU,而我们唯一的度量是周转时间,STCF将是一个伟大的策略。事实上,对于许多早期的批处理计算系统,这些类型的调度算法有一定的意义。然而,时间共享机器的引入改变了这一切。现在,用户会坐在终端上,同时要求系统的交互性能。因此,一个新的度量标准诞生了:响应时间。我们将响应时间定义为从工作到达系统到第一次运行时的响应时间。


例如,如果我们有上面的日程安排(在时间为0的情况下,B和C在时间10的时候到达),每个工作的响应时间为:0为工作A, 0为B, 10为C(平均值为3.33)。您可能会认为,STCF和相关的规程并不特别适合响应时间。例如,如果三份工作同时到达,第三份工作必须等待前两份工作全部完成,然后才安排一次。虽然对于周转时间很好,但是这种方法对响应时间和交互性都很差。实际上,想象一下坐在一个终端,输入,然后等待10秒钟。因为其他的工作安排在你的前面,所以要从系统中看到回应:不太愉快。因此,我们面临另一个问题:如何构建对响应时间敏感的调度器。

7.7循环

为了解决这个问题,我们将引入一个新的调度算法,经典地称为循环调度(RR)调度。基本的想法很简单:RR运行一个时间片(有时称为调度量子),然后切换到运行队列中的下一个作业,而不是运行作业。它反复这样做,直到工作结束。出于这个原因,RR有时被称为时间分割。请注意,时间片的长度必须是时间中断周期的倍数;因此,如果计时器每10毫秒中断一次,那么时间片可能是10、20或任何其他10毫秒的倍数。

为了更详细地理解RR,让我们来看一个例子。假设三个作业A、B和C在系统中同时到达,并且它们各自希望运行5秒钟。SJF调度器运行每个作业,然后运行另一个作业(图7.6)。相比之下,有1秒的时间片的RR会很快地完成工作(图7.7)。RR的平均响应时间为:0+1+2 3 = 1;对于SJF,平均响应时间为:0+5+10 3 = 5。

如您所见,时间片的长度对RR非常重要。它越短,在响应时间度量下的RR性能就越好。然而,将时间片做得太短是有问题的:突然之间,上下文切换的成本将主导整个性能。因此,决定时间片的长度对系统设计人员来说是一种权衡,使其足够长时间来分摊切换的成本,而不会使系统的响应时间变长。

摊销可以降低成本:一般的摊销技术是在系统固定成本的情况下使用的。减少成本(例如:通过减少操作次数,降低了系统的总成本。例如,如果时间片设置为10毫秒,而上下文切换成本为1毫秒,那么大约10%的时间花费在上下文切换上,因此被浪费了。如果我们想摊销这个成本,我们可以把时间片增加到100毫秒。在这种情况下,花在上下文切换上的时间不足1%,因此,时间分割的成本已经摊销。请注意,上下文切换的代价并不仅仅来自于保存和恢复几个寄存器的操作系统操作。当程序运行时,它们会在CPU缓存、TLBs、分支预测器和其他芯片硬件上建立大量的状态。切换到另一个作业导致这个状态被刷新,与当前正在运行的作业相关的新状态被引入,这可能会导致显著的性能损失[MB91]。如果响应时间是我们唯一的度量标准,那么具有合理时间片的RR是一个优秀的调度器。但是我们的老朋友周转时间呢?让我们再看看上面的例子。A、B和C,每个运行时间为5秒,同时到达,并且RR是带有(长)1秒的时间片的调度器。我们可以从上面的图中看出A在13,B在14,C在15,平均14。很可怕的。因此,如果周转时间是我们的衡量标准,那么RR确实是最糟糕的政策之一,这并不令人意外。直觉上,这应该是有道理的:RR所做的是尽可能长时间地把每一份工作都拉长,只在短时间内完成每个工作,然后再转到下一个工作。因为周转时间只关心工作完成时的情况,所以RR几乎是最糟糕的,在很多情况下甚至比简单的FIFO还要糟糕。更一般地说,任何政策(如RR)都是公平的,即。在较小的时间范围内,将CPU平均分配到活动进程中,将在诸如周转时间等指标上表现不佳。事实上,这是一种固有的权衡:如果你愿意不公平,你可以缩短工作时间,但代价是响应时间;如果你看重公平,响应时间就会降低,但要以周转时间为代价。这种取舍在系统中很常见;你不能有你的蛋糕,也不能吃它。

我们已经开发了两种类型的调度器。第一种类型(SJF, STCF)优化了周转时间,但对响应时间不利。第二种类型(RR)优化了响应时间,但对周转不利。我们仍然有两个需要放松的假设:假设4(工作没有I/O)和假设5(每个工作的运行时都是已知的)。接下来让我们来解决这些假设。

重叠使更高的利用率。在可能的情况下,重叠操作以最大限度地利用系统。重叠在许多不同的领域都很有用,包括在执行磁盘I/O或向远程机器发送消息时;在这两种情况下,启动操作,然后切换到其他工作是一个好主意,并提高系统的整体利用率和效率。

7.8合并输入与输出

首先,我们将放松假设4当然所有程序执行I/O。设想一个没有接受任何输入的程序:它每次都会产生相同的输出。想象一个没有产出的人:这是一棵树倒在森林里,没有人看见它;它跑起来并不重要。当作业启动I/O请求时,调度程序显然会做出决定,因为当前运行的作业不会在I/O期间使用CPU。阻塞等待I/O完成。如果I/O被发送到硬盘驱动器,进程可能会被阻塞几毫秒或更长的时间,这取决于驱动器的当前I/O负载。因此,调度器应该在那个时候安排另一份CPU的工作。当I/O完成时,调度器还必须作出决定。当出现这种情况时,就会引发一个中断,操作系统运行并移动发出I/O的进程,从阻塞状态返回到就绪状态。当然,它甚至可以决定在这一点上运行。操作系统应该如何处理每个工作。为了更好地理解这个问题,让我们假设我们有两个工作,A和B,每个都需要50 ms的CPU时间。然而,有一个明显的区别:一个运行10毫秒,然后发出一个I/O请求(假设我/Os每个都取10毫秒),而B仅仅使用CPU 50毫秒,并且不执行I/O。调度程序先运行一个,然后是B(图7.8)。


设我们正在尝试构建一个STCF调度器。这样的调度程序应该如何解释被分解为5个10毫秒的子任务,而B仅仅是一个50毫秒的CPU需求。很明显,只做一份工作,然后不考虑如何把I/O考虑进去就没有什么意义了。一种常见的方法是将A的10-ms分项作为一项独立的工作。当系统启动时,它的选择是是否安排10-ms 或50-ms B。对于STCF,选择很明确:选择较短的一个,在这种情况下,当A的第一个子任务完成时,只剩下B,它开始运行。然后提交一个新的子作业,它先抢占B,然后运行10毫秒。这样做允许重叠,在等待另一个进程的I/O完成时,一个进程使用CPU;因此,该系统得到了更好的利用(见图7.9)。因此,我们可以看到调度器如何合并I/O。通过将每个CPU处理作为作业来处理,调度器可以确保交互的进程频繁地运行。虽然这些交互式作业执行I/O,但其他cpu密集型作业运行,因此更好地利用了处理器。通过对I/O的基本方法,我们得出最终的假设:调度器知道每个作业的长度。正如我们之前所说,这可能是我们所能做出的最坏的假设。事实上,在一个通用的操作系统中(就像我们关心的那样),操作系统通常对每个工作的长度知之甚少。因此,我们如何构建一个类似于SJF/STCF的方法,而没有这样的先验知识呢?此外,我们如何将我们看到的一些想法与RR调度器结合起来,以便响应时间也相当不错。我们介绍了调度的基本思想,并开发了两种方法。第一个运行最短的工作剩余,从而优化周转时间;在所有作业之间进行第二次交替,从而优化响应时间。遗憾的是,两者都是不好的,这是系统中常见的一种平衡。我们也看到了我们如何将I/O合并到图片中,但仍然没有解决操作系统在未来看到的根本无法解决的问题。不久,我们将看到如何通过构建一个使用最近的调度程序来解决这个问题。

我们介绍了调度的基本思想,并开发了两种方法。第一个运行最短的工作剩余,从而优化周转时间;在所有作业之间进行第二次交替,从而优化响应时间。遗憾的是,两者都是不好的,这是系统中常见的一种平衡。我们也看到了我们如何将I/O合并到图片中,但仍然没有解决操作系统在未来看到的根本无法解决的问题。不久,我们将看到如何通过构建一个使用最近的调度程序来解决这个问题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值