预计阅读本页时间:-
5.4.3 磁盘臂调度算法
本小节我们将一般地讨论与磁盘驱动程序有关的几个问题。首先,考虑读或者写一个磁盘块需要多长时间。这个时间由以下三个因素决定:
1)寻道时间(将磁盘臂移动到适当的柱面上所需的时间)。
2)旋转延迟(等待适当扇区旋转到磁头下所需的时间)。
广告:个人专属 VPN,独立 IP,无限流量,多机房切换,还可以屏蔽广告和恶意软件,每月最低仅 5 美元
3)实际数据传输时间。
对大多数磁盘而言,寻道时间与另外两个时间相比占主导地位,所以减少平均寻道时间可以充分地改善系统性能。
如果磁盘驱动程序每次接收一个请求并按照接收顺序完成请求,即先来先服务(First-Come,First-Served,FCFS),则很难优化寻道时间。然而,当磁盘负载很重时,可以采用其他策略。很有可能当磁盘臂为一个请求寻道时,其他进程会产生其他磁盘请求。许多磁盘驱动程序都维护着一张表,该表按柱面号索引,每一柱面的未完成的请求组成一个链表,链表头存放在表的相应表目中。
给定这种数据结构,我们可以改进先来先服务调度算法。为了说明如何实现,考虑一个具有40个柱面的假想的磁盘。假设读柱面1l上一个数据块的请求到达,当对柱面11的寻道正在进行时,又按顺序到达了对柱面l、36、16、34、9和12的请求,则让它们进入未完成的请求表,每一个柱面对应一个单独的链表。图5-28显示了这些请求。

当前请求(请求柱面11)结束后,磁盘驱动程序要选择下一次处理哪一个请求。若使用FCFS算法,则首先选择柱面1,然后是36,以此类推。这个算法要求磁盘臂分别移动10、35、20、18、25和3个柱面,总共需要移动111个柱面。
另一种方法是下一次总是处理与磁头距离最近的请求以使寻道时间最小化。对于图5-28中给出的请求,选择请求的顺序如图5-28中下方的折线所示,依次为12、9、16、1、34和36。按照这个顺序,磁盘臂分别需要移动1、3、7、15、33和2个柱面,总共需要移动61个柱面。这个算法即最短寻道优先(Shortest Seek First,SSF),与FCFS算法相比,该算法的磁盘臂移动几乎减少了一半。
但是,SSF算法存在一个问题。假设当图5-28所示的请求正在处理时,不断地有其他请求到达。例如,磁盘臂移到柱面16以后,到达一个对柱面8的新请求,那么它的优先级将比柱面1要高。如果接着又到达了一个对柱面13的请求,磁盘臂将移到柱面13而不是柱面1。如果磁盘负载很重,那么大部分时间磁盘臂将停留在磁盘的中部区域,而两端极端区域的请求将不得不等待,直到负载中的统计波动使得中部区域没有请求为止。远离中部区域的请求得到的服务很差。因此获得最小响应时间的目标和公平性之间存在着冲突。
高层建筑也要进行这种权衡处理,高层建筑中的电梯调度问题和磁盘臂调度很相似。电梯请求不断地到来,随机地要求电梯到各个楼层(柱面)。控制电梯的计算机能够很容易地跟踪顾客按下请求按钮的顺序,并使用FCFS或者SSF为他们提供服务。
然而,大多数电梯使用一种不同的算法来协调效率和公平性这两个相互冲突的目标。电梯保持按一个方向移动,直到在那个方向上没有请求为止,然后改变方向。这个算法在磁盘世界和电梯世界都被称为电梯算法(elevator algorithm),它需要软件维护一个二进制位,即当前方向位:UP(向上)或是DOWN(向下)。当一个请求处理完之后,磁盘或电梯的驱动程序检查该位,如果是UP,磁盘臂或电梯舱移至下一个更高的未完成的请求。如果更高的位置没有未完成的请求,则方向位取反。当方向位设置为DOWN时,同时存在一个低位置的请求,则移向该位置。
图5-29显示了使用与图5-28相同的7个请求的电梯算法的情况。假设方向位初始为UP,则各柱面获得服务的顺序是12、16、34、36、9和1,磁盘臂分别移动1、4、18、2、27和8个柱面,总共移动60个柱面。在本例中,电梯算法比SSF还要稍微好一点,尽管通常它不如SSF。电梯算法的一个优良特性是对任意的一组给定请求,磁盘臂移动总次数的上界是固定的:正好是柱面数的两倍。

对这个算法稍加改进可以在响应时间上具有更小的变异(Teory,1972),方法是总是按相同的方向进行扫描。当处理完最高编号柱面上未完成的请求之后,磁盘臂移动到具有未完成的请求的最低编号的柱面,然后继续沿向上的方向移动。实际上,这相当于将最低编号的柱面看作是最高编号的柱面之上的相邻柱面。
某些磁盘控制器提供了一种方法供软件检查磁头下方的当前扇区号。对于这种磁盘控制器,还可以进行另一种优化。如果针对同一柱面有两个或多个请求正等待处理,驱动程序可以发出请求读写下一次要通过磁头的扇区。注意,当一个柱面有多条磁道时,相继的请求可能针对不同的磁道,故没有任何代价。因为选择磁头既不需要移动磁盘臂也没有旋转延迟,所以控制器几乎可以立即选择任意磁头。
如果磁盘具有寻道时间比旋转延迟快很多的特性,那么应该使用不同的优化策略。未完成的请求应该按扇区号排序,并且当下一个扇区就要通过磁头的时候,磁盘臂应该飞快地移动到正确的磁道上对其进行读或者写。
对于现代硬盘,寻道和旋转延迟是如此影响性能,所以一次只读取一个或两个扇区的效率是非常低下的。由于这个原因,许多磁盘控制器总是读出多个扇区并对其进行高速缓存,即使只请求一个扇区时也是如此。典型地,读一个扇区的任何请求将导致该扇区和当前磁道的多个或者所有剩余的扇区被读出,读出的扇区数取决于控制器的高速缓存中有多少可用的空间。例如,在图5-18所描述的磁盘中有4MB的高速缓存。高速缓存的使用是由控制器动态地决定的。在最简单的模式下,高速缓存被分成两个区段,一个用于读,一个用于写。如果后来的读操作可以用控制器的高速缓存来满足,那么就可以立即返回被请求的数据。
值得注意的是,磁盘控制器的高速缓存完全独立于操作系统的高速缓存。控制器的高速缓存通常保存还没有实际被请求的块,但是这对于读操作是很便利的,因为它们只是作为某些其他读操作的附带效应而恰巧要在磁头下通过。与之相反,操作系统所维护的任何高速缓存由显式地读出的块组成,并且操作系统认为它们在较近的将来可能再次需要(例如,保存目录块的一个磁盘块)。
当同一个控制器上有多个驱动器时,操作系统应该为每个驱动器都单独地维护一个未完成的请求表。一旦任何一个驱动器空闲下来,就应该发出一个寻道请求将磁盘臂移到下一个将被请求的柱面处(假设控制器允许重叠寻道)。当前传输结束时,将检查是否有驱动器的磁盘臂位于正确的柱面上。如果存在一个或多个这样的驱动器,则在磁盘臂已经位于正确柱面处的驱动器上开始下一次传输。如果没有驱动器的磁盘臂处于正确的位置,则驱动程序在刚刚完成传输的驱动器上发出一个新的寻道命令并且等待,直到下一次中断到来时检查哪一个磁盘臂首先到达了目标位置。
上面所有的磁盘调度算法都是默认地假设实际磁盘的几何规格与虚拟几何规格相同,认识到这一点十分重要。如果不是这样,那么调度磁盘请求就毫无意义,因为操作系统实际上不能断定柱面40与柱面200哪一个与柱面39更接近。另一方面,如果磁盘控制器能够接收多个未完成的请求,它就可以在内部使用这些调度算法。在这样的情况下,算法仍然是有效的,但是低了一个层次,局限在控制器内部。