【2021/7/19更新】【梳理】简明操作系统原理 第十二章 机械硬盘 磁盘I / O的调度(docx)

本文深入探讨了操作系统中机械硬盘的磁盘I/O调度,引用了权威教材和参考书目进行讲解。内容包括平均寻道时间和最大寻道时间的计算,以及随机访问时寻道路程的分析,揭示了平均寻道路程与盘片尺寸的关系。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

配套教材:
Operating Systems: Three Easy Pieces Remzi H. Arpaci-Dusseau Andrea C. Arpaci-Dusseau Peter Reiher
参考书目:
1、计算机操作系统(第4版) 汤小丹 梁红兵 哲凤屏 汤子瀛 编著 西安电子科技大学出版社

在线阅读:
http://pages.cs.wisc.edu/~remzi/OSTEP/
University of Wisconsin Madison 教授 Remzi Arpaci-Dusseau 认为课本应该是免费的
————————————————————————————————————————
这是专业必修课《操作系统原理》的复习指引。
需要掌握的概念在文档中以蓝色标识,并用可读性更好的字体显示 Linux 命令和代码。代码部分语法高亮。
文档下载地址:
链接:https://pan.baidu.com/s/1mm4jSFQvAC0IgpBJGbFE1A
提取码:0000

十二 机械硬盘 磁盘I / O的调度

机械硬盘(Hard disk drive,HDD)本身是按照扇区(sector)为最小单位进行存储的。以前,硬盘的扇区大小一般为512 Bytes;较新的硬盘则采用4 KB作为单个扇区的大小。但是4 KB扇区需要操作系统的支持。为了使硬盘在较老的操作系统上能够被识别,硬盘厂商通过固件(firmware)将4 KB的物理扇区模拟成512字节的逻辑扇区。

固件是安装在设备的硬件中的软件,和驱动(需要安装在操作系统内)没有明显的界限,但一般而言固件要更加接近于硬件底层。通常情况下,固件不允许被修改。
硬盘对扇区的读写是原子性的。如果读写过程中突然断电,未写入的数据就会丢失。

机械硬盘内部有若干个盘片(platter),它们是圆形的,一般由铝制成,表面极其光滑(你可以把报废的盘片拆下来当镜子用),双面都附有磁性材料来存储数据。盘片都被固定在主轴(spindle)上,随主轴一起转动。硬盘启动后,盘片的转速一般为5400 RPM或7200 RPM。少数服务器硬盘转速达到10000 RPM甚至15000 RPM。当然,现在也比较少见了。因为高转速对加工的要求很高,而且转速过高可能导致盘片因为原子间提供的向心力不足而直接破碎。另外,高转速带来的发热量也是非常大的。盘片的直径多为2.5英寸或3.5英寸。以前有5.25英寸的硬盘,但是转速也无法做得过快。
其它规格都相同的情况下,转速越高,读写速率越快。7200 RPM硬盘的读写速率一般高于5400 RPM硬盘。
盘片被划分为大量的同心圆,每个同心圆称为一个磁道(track,有的软件也写作磁头,但不要将其把用于读取数据的磁头搞混)。单个盘片的磁道数量非常大,目前每张盘片的容量可以做到2 TB。
每张盘片的两面各有一个磁头(disk head),与磁臂(disk arm)连接,被驱动电路控制,用于在不同的磁道、扇区进行读写。

如图。磁盘启动后,磁头会迅速移到盘片上方。在磁道间读写时,磁头的移动速度是非常快的。磁头通过空气动力学设计浮在盘片上方,距离盘片非常近。空气过滤片过滤空气中的灰尘。盘片对无尘的要求非常严格,所以硬盘被严格密封。不要自行拆开硬盘,否则这个硬盘就会马上报废。硬盘中的永磁铁的磁性非常大,如果你拆开了一个报废的硬盘,玩永磁铁的时候千万要小心。若你不够当心,在磁铁与其它物体吸住的时候,你的手指很可能就会马上变成肉泥。

收到读写扇区的命令后,磁盘会找到扇区所在的磁道,磁头会先从当前所在的位置移过去。这个过程需要的时间称为寻道时间(seek time)。具体来说,磁头从当前位置开始加速,然后保持一定的速度滑行,再减速,最后靠在正确的磁道上。为了使磁头能正确定位磁道,最后一步耗费的时间也是最多的。
然后,磁盘等待扇区转到磁头可以达到的位置。差不多到达这个位置以后,磁头就进行读写。这个等待的过程称为旋转延迟(rotational delay)。平均旋转延迟是盘片转过半圈的时间。
这时候,传输数据的过程才正式开始。
读写完毕后,磁头留在原位。因为过度频繁地移动磁头会耗损其寿命。
由此我们得出:磁盘I / O的总时间 = 寻道时间 + 旋转延迟 + 传输时间。即

T_IO=T_S+T_R+T_t

现在的硬盘采用了磁道偏移(track skew)方式来划分磁道和扇区。下面的图中,右侧是采用了该技术的硬盘。
注意对比两张图的扇区11和12、23和24的相对位置有什么不同。这种方式能使顺序读取的过程中,磁头切换下一条磁道读取时,能够直接从下一个扇区开始读。如果不使用该方式划分磁道和扇区,磁头在切换下一个磁道时,下一个编号的扇区已经在切换磁道的过程中随着盘片的旋转而离开了磁头的位置。若要继续读取此扇区,只能再等盘片转一圈。

这两张图只是为了便于理解而绘制的。事实上,但凡稍微新一点的硬盘中,外侧的磁道拥有的扇区数都要更多。现在说的“每磁道扇区数”,是一个换算出来的平均值。
机械硬盘都会具有缓存(以前叫做磁道缓冲区,track buffer)。读取数据时,被读取的数据连同附近的数据一起被读入缓存中,以此加快访问速率。在写入数据时,数据也会先写入到缓存,之后再由硬盘正式写入到盘片上。
磁盘在写入时,有两种方式,分别是回写(write back)和直写(write through)。使用前者时,只要写入的数据全部交给了磁盘(即使有数据还在缓存内),就报告写入已经完毕;使用后者时,只有数据真正写入到盘片上,才报告写入完毕。Write back方式看上去写入速率更高,但如果在磁盘将缓存中的数据写入的过程中断电,未写入盘片的数据将丢失。缓存加快读写速率的原理在第6章已经讲过了。

简单学习了磁盘读写的基本步骤之后,很容易想到:顺序读取的速率一定远远高于随机读取,因为随机读取意味着要耗费大量时间在寻道和旋转延迟上。如果频繁请求小文件的随机读写,性能会降低得非常难看。在编写代码的时候也要注意,如果可能,尽量将小的I / O凑在一起一次性进行。
由下面的几张图片可以看出顺序读写和小文件读写的性能差距。如果是小文件随机读写,性能就更低了(Pic via Anandtech)。并且,小文件大概率是在硬盘上随机分布的。



理论上,平均寻道时间是最大寻道时间的约1 / 3。下面我们来证明这个结论。
设磁道从0编号到N,N→+∞(一块磁盘具有非常多的磁道)。从任意一个磁道x寻道至y需要走过的路程近似用|x-y|长度单位表示。于是所有的寻道轨迹的路程之和就是

∑_(x=0)^N▒  ∑_(y=0)^N▒  |x-y|
由乘法原理,共有N2种不同的寻道请求。因此上式除以N2就得到平均的寻道路程。
设寻道的平均速率是不变的,那么平均寻道时间与最大寻道时间的比值就由两种情况下磁头走过的路程决定了。
因为N很大,所以上面的式子可以近似为积分式
∫_(x=0)^N▒  ∫_(y=0)^N▒  |x-y|dydx
我们先算内层积分。去掉绝对值,得:
∫_(y=0)^x▒  (x-y)dy+∫_(y=x)^N▒  (y-x)dy
上式已经可以直接解出,结果为:
├ (xy-1/2 y^2 )┤|0^x+├ (1/2 y2-xy)┤|_xN
化简并代入原积分式,得:
(x=0)^N▒  (x^2-Nx+1/2 N^2 )dx
这个积分式也可以直接解出,结果为:
├ (1/3 x^3-1/2 Nx^2+1/2 N^2 x)┤|_0^N=1/3 N^3
如果访问是完全随机的,那么N越大,N^2次寻道中磁头走过的总路程就越接近该值。
将其除以N^2,就得到平均寻道路程为1/3 N。
最大寻道路程自然就是从盘片的最外沿到最内沿,路程为N。结论得证。

一系列I / O请求产生(或累积)后,磁盘调度器(disk scheduler)负责调度这些磁盘I / O请求。与进程 / 线程调度不同,我们一般无法得知进程 / 线程何时结束,但可以根据需要访问的位置和磁头的当前位置算出磁盘的寻道时间和延迟。因此磁盘调度器倾向于选择最短作业优先(SJF)的调度原则。
先来先服务(FCFS)是非常简单的调度算法,未针对机械硬盘的寻道原理进行优化。该方法的平均寻道距离较长,仅适用于磁盘I / O较少的场合。
最短寻道时间优先(shortest seek time first,SSTF),或最短寻道优先(shortest seek first,SSF),是很早就产生的磁盘I / O调度方法。目标磁道离磁头的当前位置最近的I / O请求会被最先处理。
但SSTF并不是万能的,因为磁盘的几何结构并不为操作系统所知,操作系统只把磁盘当成一个由块组成的一维连续结构。不过这个问题非常容易解决,操作系统容易实现最近块优先(nearest block first,NBF)算法,让离访问过的块最近的I / O请求最先被处理。
而且,SSTF容易让部分请求长期饥饿,因为硬盘总是最先响应离当前磁头位置更近的寻道请求。

电梯调度,也称SCAN,它的基本思想很简单:不断地由盘片外圈移至内圈,再由内圈移至外圈,如此往复,很像建筑物里的电梯那样反复升降。磁头完整地从外圈移至内圈或从内圈移至外圈一次,称为一次扫描(sweep)。这个算法总是从磁臂当前位置开始,沿磁臂的移动方向去选择离当前磁臂最近的那个柱面的访问者。如果沿磁臂的当前移动方向无请求访问,就改变磁臂的移动方向。如果某个请求所在的块在最近一次扫描中已经处理过,它将不被立即处理。
SCAN算法有很多变体。
在SSTF、SCAN及CSCAN几种调度算法中,都可能出现磁臂停留在某处不动的情况,例如,有一个或几个进程对某一磁道有较高的访问频率,即这些进程反复请求对某一磁道的I / O操作,从而垄断了整个磁盘设备。我们把这一现象称为“磁臂粘着”(Arm stickiness)。在高密度磁盘上容易出现此情况。N-Step-SCAN算法是将磁盘请求队列分成若干条长度为N的子队列,磁盘调度将按FCFS算法依次处理这些子队列。而每处理一条队列时又是按SCAN算法,对一条队列处理完后,再处理其它队列。当正在处理某子队列时,如果又出现新的磁盘I / O请求,便将新请求进程放入其它队列,这样就可避免出现粘着现象。当N值取得很大时,会使N步扫描法的性能接近于SCAN算法的性能;当N=1时,N步SCAN算法便退化为FCFS算法。
C-SCAN的C代表Circular(循环)。这种算法只从外圈向内圈扫描。一轮扫描完毕后,磁头重新回到最外圈。C这个算法对靠近内圈和外圈的I / O请求更公平一点:双向的往复扫描可能让部分外圈和内圈的I / O请求饥饿时间较长。
举个生活中的简单例子,你就能更好地体会电梯算法的优势了:假如电梯里只有你一人,你从30楼下到1楼,有个人从10楼进来了,按了15楼。如果电梯总是去往最近的楼层,那么它就会先到15楼。如果15楼又有个人上来了,他按了13楼,电梯就到13楼;13楼又有个人上来了,他按了18楼,电梯就又上升到18楼……当轮到你到达1楼的时候,时间已经不知道过去多久了。
F-SCAN是N步SCAN算法的简化。该算法在扫描进行的过程中冻结请求队列,在扫描期间到来的请求全部被延后至下一轮扫描再处理。这确保了每个I / O请求的饥饿时间都不长。

不过,SCAN和SSTF并没有考虑盘片的旋转造成的影响。在介绍最短定位时间优先(shortest positioning time first,SPTF,或最短访问时间优先,shortest access time first,SATF)之前,先举一个例子:

现在在扇区30。一堆磁盘I / O请求过来了,一个是16,一个是8。先处理哪个呢?我们进行分类讨论。
如果寻道时间比旋转延迟长得多,使用SSTF及其变种更佳,先访问扇区16;但如果旋转延迟比寻道时间长,访问8则更优。因为如果访问16则意味着要等盘片转上差不多一圈才能访问到它。
但在较新的机械硬盘中,寻道和旋转时间一般差不多(当然在有些情况下有区别),于是SPTF算法就能更好发挥性能了。只是,这个方法更难被操作系统实现,因为操作系统并不能知道磁道边界在哪里,也不知道此时磁头在哪个位置,所以这个算法通常由磁盘自行实现。

以往,操作系统负责全部的磁盘调度。而现代系统中,磁盘负责大部分的调度。操作系统通常只简单告诉磁盘它认为的一些最优位置,磁盘便接手剩余的调度决策。
操作系统也负责将邻近位置的磁盘I / O合并。这可以减少I / O请求的数量,减轻硬盘控制芯片的压力,并且还能提升读写速率。
此外,操作系统如何知道当I / O数量非常少的时候要等待多久?有的操作系统选择令磁盘连续工作(称为work-conserving),于是一有磁盘I / O到来就立刻让磁盘进行读写;而相对的是预期磁盘调度(anticipatory disk scheduling),当I / O请求非常少时,先等待一定时间,以便在收集到更多的I / O请求后做出一个更优的调度方案,也可以将邻近区域的磁盘I / O请求合并,提升性能。能力足够的同学可以查阅相关的论文或Linux内核代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值