本章小结:
- 旋转硬盘驱动器的构造和组织
- 旋转硬盘的访问时间
- 磁盘调度和缓存
- 固态硬盘
旋转硬盘
构造
旋转硬盘驱动器由覆盖有可磁化材料的铝/玻璃盘片(platters)制成
- 读/写头刚刚高于表面(0.2 - 0.07毫米),并连接到一个由单个执行器控制的单个的磁盘臂
- 数据存储在两边
- 常见的直径范围从1.8到3.5英寸
- 它们以恒定的速度旋转(主轴附近的转速小于主轴外的转速)。
磁盘控制器抽象了底层接口
旋转硬盘大约比主存慢4个数量级

低级格式化
低级格式化(Low Level Format):
低级格式化是指对磁盘或磁盘分区进行初始化的一种操作,通常会清除现有的磁盘或分区中所有资料。
磁盘按以下方式组织:
- 柱面(Cylinders):所有导轨相对于主轴处于同一位置
- 轨道(Tracks):一个同心圆在一个单一的盘片的一面
- 扇区(Sectors):磁道的段(通常是512B或4KB大小)
扇区通常有相等的字节数(前文,数据,纠错码(error correcting code,ECC))
扇区的数量从磁盘的内侧向外侧增加
组织
五分钟聊完磁盘 - 简书 (jianshu.com)
https://www.jianshu.com/p/eee541370d08柱面斜进(Cylinder skew)是一种偏移量,它被添加到相邻磁道的扇区中,以解释寻道时间
在过去,连续的磁盘扇区是交错的,以考虑传输时间
由于低级格式化(preamble, ECC等),磁盘容量减少。
存取时间
存取时间/访问时间:
指计算机系统中从请求发出到响应返回所经过的时间。
访问时间=寻道时间+旋转延迟+传输时间(Access time = seek time + rotational delay + transfer time)
- 寻道时间:将手臂移动到圆柱体(优势)所需的时间
- 旋转延迟:扇区在磁头下出现之前的时间
- 传输时间:传输数据的时间
多个请求可能同时发生(并发)。因此,访问时间可能会增加排队时间
通过仔细考虑读操作的顺序,寻道时间的优势为优化留出了空间

将臂从一条轨迹移动到另一条轨迹的估计寻道时间 近似为:
- n:要穿过的轨道数
- m:每条轨道穿过的时间
- s:任何额外的启动延迟
假设磁盘的转速为3600rpm(通常转速在3600~15000 rpm):
- 一次旋转大约需要16.7毫秒(
)
- 平均旋转延迟(
)平均为半圈(
ms)
设b表示传输的字节数,N表示每个磁道的字节数,rpm(revolutions per minute)表示每分钟的转速。传输时间 为:
- N个字节需要1转(16.7ms)
- b个连续字节需要
转:
例子
读取大小为256扇区的文件,使用:
= 20 ms(平均寻道时间)
- 32个扇区/轨道
如果文件是连续存储的:
- 第一个轨道:20+8.3+16.7 = 45ms(寻道+旋转延迟+传输时间)
- 剩余轨道(假设没有柱面斜进,相邻轨道之间的寻道时间可以忽略不计):8.3+16.7 = 25ms(旋转延迟+传输时间)
总时间为45+7×25 = 220ms = 0.22s
如果扇区的访问不是顺序的而是随机的,我们得到:
- 每扇区时间
- 256个扇区的总时间 = 256×28.8ms = 7.37s
观察:扇区必须仔细定位,避免磁盘碎片
磁盘调度
概念
操作系统/硬件必须:
- 战略性地定位/组织文件和扇区
- 优化磁盘请求以最小化寻道时间和旋转延迟带来的开销
I/O请求随着时间的推移而发生,经过系统调用并排队:
- 它们保存在每个柱面请求扇区的表中
- 这允许操作系统拦截并重新排序它们
磁盘调度算法确定处理磁盘请求的顺序,以最小化开销
- 他们通常使用启发式方法
- 也就是说,这里讨论的算法都不是最优算法
假设一个有36个柱面的磁盘,编号从1到36
先到先服务
先到先得(First come first served):按照请求到达的顺序处理请求
考虑以下磁盘请求序列(柱面位置):
11 1 36 16 34 9 12
按到达顺序(FCFS),总长度为:
| 11-1 | + | 1-36 | + | 36-16 | + | 16-34 | + | 34-9 | + | 9-12 | = 111
最短寻道时间优先
最短寻道时间首先(Shortest seek time first)选择最接近当前头部位置的请求
按照“最短寻道时间优先”(SSTF)的顺序,我们获得了大约50%:
11 1 36 16 34 9 12:
|11-12|+|12-9|+|9-16|+|16-1|+|1-34|+|34-36|=61
最短寻道时间优先可能导致饥饿:
- 在重载情况下,臂保持在磁盘的中间(边缘柱面的服务很差)
- 不断到达同一位置的请求可能会使其他区域挨饿
SCAN
“Lift algorithm, SCAN”:保持同一方向移动,直到到达终点(开始向上);
- 它继续在当前方向上运行,在经过所有挂起的请求时为它们提供服务
- 当到达最后一个柱面时,它将反转方向并服务所有挂起的请求(直到到达第一个圆柱体)。
优缺点包括:
- “等待时间”的上限是2倍的柱面数,即不发生饥饿
- 如果磁盘被大量使用,中部柱面是最好的。最大等待时间为N轨道,边缘柱面为2N)
“提升算法,SCAN”:
11 1 36 16 34 9 12:
|11-12|+|12-16|+|16-34|+|34-36|+|36-9|+|9-1|=60
其他扫描变体:LOOK-SCAN, N-step-SCAN
Look-SCAN移动到包含第一个/最后一个请求的柱面(而不是SCAN磁盘上的第一个/最后一个柱面)
寻道是一个柱面接一个柱面,一个柱面包含多个轨道
臂可以粘在柱面上
N-step-SCAN(N步扫描)每次扫描只服务N个请求。
C-SCAN
一旦到达磁盘的外部/内部,磁盘另一端的请求等待的时间最长
SCAN可以通过使用循环扫描(circular scan)方法来改进 ⇒ C-SCAN
- 磁盘臂在服务请求的一个方向上移动,直到到达最后一个柱面
- 它反转方向,但在返回时不处理请求
- 一旦它返回到第一个柱面,它将反转方向并处理请求
- 它更公平,并且可以均衡整个磁盘的响应时间
C-SCAN 算法 (对于 11 1 36 16 34 9 12):
|11-12|+|12-16|+|16-34|+|34-36|+|36-1|+|1-9|=68
观察
Look-SCAN和变体是算法的合理选择
算法的性能取决于磁盘的请求/负载:一次一个请求 ⇒ FCFS的性能和其他算法一样好
如果请求经过一段时间到达,则很难实现最优算法(它们需要对信息有充分的了解)。
Unix/Linux中的磁盘调度
修改磁盘调度程序
在Linux中,我们可以通过修改文件来修改磁盘调度器:/sys/block/sda/queue/scheduler
我们有三个策略:
- noop:这是FCFS的
- deadline:N-step-SCAN
- cfq:来自Linux的完全公平排队(Complete Fairness Queueing)。
括号之间的是当前的政策。
pszgd@severn:~$ cat /sys/block/sda/queue/scheduler
noop [deadline] cfq
固态硬盘(Solid State Drives,SSDs)
驱动程序缓存:对于大多数当前驱动器,寻找新柱面所需的时间大于旋转时间(在此上下文中请记住预分页!)
因此,读取比实际需要更多的扇区是有意义的
- 在旋转延迟期间读取扇区(即意外通过)
- 当要求从一个扇区读取数据时,现代控制器读取多个扇区:每次跟踪(track-at-a-time)缓存
架构
固态硬盘(SSD):
- 没有移动部件,使用单级(SLC),多级(MLC),三级(TLC)电路,并遭受磨损和干扰
- 组织成排(banks),块(blocks),页(pages),并有一些易失性缓存(缓冲,映射表)
- 经常并行使用多个排(复接排)来提高性能

读/写
将逻辑块映射到物理页面的闪存转换层(Flash Translation Layer)
支持如下操作:
- 读取:均匀快速随机访问任何页面到任何位置(10微秒)
- 擦除:包含多个页面的整个块(毫秒级)
- 编程:写一个页面(100微秒,必须先擦除块)
SSD写操作:




直接映射
逻辑页(由操作系统看到)直接映射到物理页
- 阅读给定页面的整个块
- 擦除整个块
- 将新页面和剩余的旧页面写回去
写性能差(写入放大)和磨损增加(一些块比其他块使用得更多)⇒需要一种不同的日志结构方法
写入放大(write amplification):
写入放大是闪存和SSD中的不良现象,实际写入的物理数据量是写入数据量的多倍
理解
磁盘访问次数:
按照这个顺序,磁盘请求进入到磁盘驱动程序的柱面为10、22、20、2、40、6和38。
- 每个圆柱体需要6ms。
- 需要多少寻道时间:FCFS, SSTF和Look-SCAN(最初向上移动)
- 在所有情况下,臂最初都在20号柱面上。
1. FCFS(先来先服务)
按请求顺序处理:10, 22, 20, 2, 40, 6, 38。初始位置20。
-
20 → 10: 移动10个柱面(|20-10|=10)
-
10 → 22: 移动12个柱面(|10-22|=12)
-
22 → 20: 移动2个柱面(|22-20|=2)
-
20 → 2: 移动18个柱面(|20-2|=18)
-
2 → 40: 移动38个柱面(|2-40|=38)
-
40 → 6: 移动34个柱面(|40-6|=34)
-
6 → 38: 移动32个柱面(|6-38|=32)
总移动柱面数:10 + 12 + 2 + 18 + 38 + 34 + 32 = 146
寻道时间:146 * 6ms = 876ms
2. SSTF(最短寻道时间优先)
总是选择距离当前磁头位置最近的请求。初始位置20。
请求序列:10,22,20,2,40,6,38(注意20就在初始位置,所以立即处理,移动0)。
处理顺序:
-
当前20:最近的有20(距离0)、22(距离2)、10(距离10)→ 先处理20(移动0),移除请求20。
剩余:10,22,2,40,6,38 -
当前20:最近有22(距离2)和10(距离10)→ 选22(移动2)
剩余:10,2,40,6,38 -
当前22:最近有38(距离16)和10(距离12)→ 选10(移动12)
剩余:2,40,6,38 -
当前10:最近有6(距离4)和2(距离8)→ 选6(移动4)
剩余:2,40,38 -
当前6:最近有2(距离4)和38(距离32)→ 选2(移动4)
剩余:40,38 -
当前2:最近有38(距离36)和40(距离38)→ 选38(移动36)
剩余:40 -
当前38→40:移动2
移动柱面数:0(20) + 2(20→22) + 12(22→10) + 4(10→6) + 4(6→2) + 36(2→38) + 2(38→40) = 60
寻道时间:60 * 6ms = 360ms
3. LOOK-SCAN(初始向上移动)
初始向上移动,处理所有大于等于当前位置的请求(升序),然后反向处理剩余请求(降序)。
初始位置20,向上移动。
首先处理所有≥20的请求:20,22,38,40(按升序:20,22,38,40)
然后处理所有<20的请求:10,6,2(按降序:10,6,2)
具体路径:
-
从20开始(处理20)
-
向上到22(处理22)
-
继续向上到38(处理38)
-
继续向上到40(处理40)
-
然后反向,向下到10(处理10)
-
向下到6(处理6)
-
向下到2(处理2)
移动柱面数:
-
20→22: 2
-
22→38: 16
-
38→40: 2
-
40→10: 30(因为从40直接到10)
-
10→6: 4
-
6→2: 4
总移动:2+16+2+30+4+4 = 58
寻道时间:58 * 6ms = 348ms
注意:初始位置20,第一个请求20无需移动(但已在路径中,从20开始处理,然后移动到22,所以20→22是2柱面)。
总结:
-
FCFS: 876ms
-
SSTF: 360ms
-
LOOK-SCAN: 348ms
最终答案:
-
FCFS寻道时间:876ms
-
SSTF寻道时间:360ms
-
LOOK-SCAN寻道时间:348ms
604

被折叠的 条评论
为什么被折叠?



