工作负载假设
为了方便概念的描述,对操作系统中运行的进程(有时也叫工作任务)做出如下的假设:
- 每一工作运行相同的时间
- 所有的工作同时到达。
- 一旦开始,每个工作保持运行直到完成。
- 所有的工作只是用 CPU(即它们不执行 IO 操作)。
- 每个工作的运行时间是已知的。
调度指标
除了做出工作负载假设之外,还需要一个东西能让我们比较不同的调度策略:调度指标。
任务的周转时间定义为任务完成时间减去任务到达系统的时间。
T 周转时间= T 完成时间−T 到达时间
因为我们假设所有的任务在同一时间到达,那么 T到达时间 = 0,因此 T周转时间= T完成时间。随着我们放宽上述假设,这个情况将改变。
周转时间是一个性能指标,而另一个有趣的指标是公平。性能和公平在调度系统中往往是矛盾的。例如,调度程序可以优化性能,但代价是以阻止一些任务运行,这就降低了公平。
先进先出(FIFO)
先进先出(First In First Out 或 FIFO)调度,有时候也称为先到先服务(First Come First Served 或 FCFS)。
FIFO 有一些积极的特性:它很简单,而且易于实现。而且,对于我们的假设,它的效果很好。
假设有三个几乎同时到达的进程,到达顺序为 A,B,C,B 和 C 执行 10s,A 有执行 10s 和执行 100s 的情况,调度结果如下图:
两者的平均周转周期
- 左:(10 + 20 + 30)/3 = 20
- 右:(100 + 110 + 120)/3 = 110
这个问题通常被称为护航效应(convoy effect),一些耗时较少的潜在资源消费者被排在重量级的资源消费者之后。
最短任务优先(SJF)
最短任务优先(Shortest Job First,SJF):先运行最短的任务,然后是次短的任务,如此下去
左图是在上一节条件下使用 SJF 策略时的表现,右图是在到达时间间隔 10s 条件下使用 SJF 策略时的表现:
两者的平均周转周期
- 左:(10 + 20 + 120)/3 = 50
- 右:(100+(110−10)+(120−10))/3 = 103.33
从图中可以看出,当 ABC 几乎同时到达时,SJF 相较于 FIFO 有较好的表现,但当 B 和 C 在 A 之后不久到达,由于 SJF 无法抢占,它们仍然被迫等到 A 完成,从而遭遇同样的护航问题。
最短完成时间优先(STCF)
我们放宽第一节提出的假设条件 3(工作必须保持运行直到完成),也就是允许抢占
向 SJF 添加抢占,称为最短完成时间优先(Shortest Time-to-Completion First,STCF)或抢占式最短作业优先(Preemptive Shortest Job First ,PSJF)调度程序
每当新工作进入系统时,它就会确定剩余工作和新工作中,谁的剩余时间最少,然后调度该工作:
平均周转周期为:
- (120 + 10 + 20)/3 = 50
新度量指标:响应时间
响应时间定义为从任务到达系统到首次运行的时间。
T 响应时间= T 首次运行−T 到达时间
用户将会坐在终端前面,同时也要求系统的交互性和响应性好,所以响应时间是有意义的
轮转
轮转(Round-Robin,RR)调度:在一个时间片(time slice,有时称为调度量子,scheduling quantum)内运行一个工作,然后切换到运行队列中的下一个任务,而不是运行一个任务直到结束。它反复执行,直到所有任务完成。因此,RR 有时被称为时间切片(time-slicing)。
请注意,时间片长度必须是时钟中断周期的倍数。因此,如果时钟中断是每 10ms 中断一次,则时间片可以是 10ms、20ms 或 10ms 的任何其他倍数。
来看一个例子:假设 3 个任务 A、B 和 C 在系统中同时到达,并且它们都希望运行 5s。
平均响应时间:
- SJF:(0 + 5 + 10)/ 3 = 5
- RR:(0 + 1 + 2)/3 = 1
时间片长度对于 RR 是至关重要的。时间片长度越短,RR 在响应时间上表现越好。然而,时间片太短是有问题的:突然上下文切换的成本将影响整体性能。因此,系统设计者需要权衡时间片的长度,使其足够长,以便摊销(amortize)上下文切换成本,而又不会使系统不及时响应(书上53页介绍了摊销的基本知识)
结合I/O
首先,我们将放宽假设 4:所有程序都不执行 I/O。
一种常见的方法是将 A 的每个 10ms 的子工作视为一项独立的工作。因此,当系统启动时,它的选择是调度 10ms 的 A,还是 50ms 的 B。对于 最短完成时间优先(STCF),选择是明确的:选择较短的一个,在这种情况下是 A。然后,A 的工作已完成,只剩下 B,并开始运行。然后提交 A 的一个新子工作,它抢占 B 并运行 10ms。这样做可以实现重叠(overlap),一个进程在等待另一个进程的 I/O 完成时使用 CPU,系统因此得到更好的利用
有了应对I/O的基本方法,我们来到最后的假设5:调度程序知道每个工作的长度。如前所述,这可能是可以做出的最糟糕的假设。事实上,操作系统通常不知道每个作业的长度。因此,我们将在第8章利用最近的历史预测未来,从而解决这个问题。
小结
我们介绍了调度的基本思想,并开发了两类方法。第一类(SJF,STCF)是运行最短的工作,从而优化周转时间(但对响应时间不利)。第二类(RR)是交替运行所有工作,从而优化响应时间(但对周转时间不利)。
补充
等待时间
等待时间是书上没有的内容,结果期中考试考了,无语子😅 😅 😅
对于计算机的用户来说,他们希望自己的作业尽可能少的等待处理机。于是人们又提出了一个衡量指标, 等待时间。
等待时间,是指进程/作业处于等待处理机状态的时间之和,显然,等待时间越长,用户满意度越低。公式如下。
等待时间=周转时间−运行时间
参考
https://github.com/2w1nd/os-study/tree/main/%E8%99%9A%E6%8B%9F%E5%8C%96
https://hjk.life/posts/operating-systems-5/
https://www.cnblogs.com/shuo-ouyang/p/12740241.html
《操作系统导论》