408 · 操作系统 · 第 5 章

输入输出管理

这一章的主线只有一条:CPU 太快,设备太慢,还五花八门。硬件上让 CPU 越管越少(中断、DMA、通道),软件上分层屏蔽差异,再用缓冲和假脱机把速度差垫平。最后单讲最重要的块设备:磁盘,以及怎么排磁道请求。

CPU 介入的粒度越来越粗程序查询和中断按字,DMA 按块,通道按一组块。粒度越粗,CPU 被打断越少,并行度越高
速度差靠“中间垫一层存储”缓冲区在内存里,SPOOLing 的输入井、输出井在磁盘上。缓冲只是削峰,假脱机还把独占设备变成了共享设备
磁盘慢在机械运动访问时间 = 寻道 + 旋转延迟 + 传输。磁盘调度算法只能缩短寻道时间,后两项由转速决定
一 · 演进导图

每一步都在解决上一步留下的问题

I/O 管理让慢且杂的设备别拖累快 CPU:控制方式(硬件)+ 分层软件 + 缓冲 / 假脱机 + 磁盘调度
I/O 控制方式数据怎么在设备和内存之间搬,CPU 要管多少

程序直接控制

忙等
做法
CPU 发命令后反复读状态寄存器,就绪了再读一个字
新问题
CPU 大部分时间在空转等设备,CPU 与 I/O 串行

中断驱动

每字一次中断
做法
CPU 发完命令去干别的,设备准备好一个字就发中断
新问题
数据仍要经过 CPU 寄存器;块设备一次几 KB,中断次数太多

DMA

每块一次中断
做法
DMA 控制器直接在设备和内存之间搬一整块,只在块开始和结束时找 CPU
新问题
一个 DMA 控制器只管一种传送,读多个不连续块、控制多台设备仍需 CPU 逐次安排

通道

一组块一次中断
做法
专用的 I/O 处理机,执行内存里的通道程序,完成一整组块的传送
代价
硬件贵;通道指令类型单一,没有自己的内存,和 CPU 共享主存
缓冲与虚拟设备在快慢两端之间垫一层存储

无缓冲

问题
设备每送来一点数据 CPU 就得立刻取走,速度差完全暴露,中断频繁

单缓冲

max(C, T) + M
做法
内存里开一块缓冲区,设备先写满它,再整体传到用户区
新问题
传送 M 期间缓冲区被占,设备只能停

双缓冲

max(C + M, T)
做法
两块缓冲区轮流用:一块往用户区传时,设备往另一块写
局限
生产与消费速度差很大时,两块也不够

循环缓冲 / 缓冲池

做法
多个缓冲区连成环;或全系统共享一个池,按需领取、用完归还
好处
内存利用率高,适合多个进程共享

SPOOLing 假脱机

独占 → 共享
解决
打印机这类独占设备一次只能给一个进程,别人只能等
做法
在磁盘上开输入井 / 输出井,每个进程“以为”自己独占了一台设备
磁盘调度一串磁道请求,按什么顺序服务

FCFS 先来先服务

做法
按请求到达顺序
新问题
请求分散时磁头来回乱跑,寻道很长

SSTF 最短寻找时间优先

可能饥饿
做法
每次挑离磁头最近的请求
新问题
近处请求源源不断时,远处的请求一直等

SCAN 扫描(电梯)

做法
沿一个方向服务到磁盘端点才掉头
新问题
两端的请求要等很久,中间磁道被扫到的频率更高

C-SCAN 循环扫描

做法
只在一个方向服务,到端点后直接回到另一端,返回途中不服务
效果
各磁道等待时间更均匀

LOOK / C-LOOK

做法
不走到端点,到该方向最远的请求就掉头(或返回)
效果
省掉到端点的空行程

和计组联动:中断响应、DMA 的三种访存冲突处理(停止 CPU 访存 / 周期挪用 / 交替访存)、CPU 占用率计算在计组第 7 章考;OS 这边侧重“谁来控制、CPU 干预几次”和软件层次。

二 · I/O 设备与设备控制器

CPU 不直接碰设备,它只读写控制器里的寄存器

设备的机械部分千差万别,电子部分(设备控制器 / I/O 接口)把它包装成几个寄存器。CPU 往控制寄存器写命令,从状态寄存器读状态,通过数据寄存器交换数据。

分类依据类别特点例子
信息交换单位块设备以数据块为单位传输;传输快,可寻址,可随机读写任一块;常用 DMA磁盘、SSD
字符设备以字符为单位;传输慢,不可寻址;常用中断驱动键盘、鼠标、打印机
传输速率低速 / 中速 / 高速每秒几字节到几百字节 / 数千到数万字节 / 数百 KB 到数 MB 以上键盘鼠标 / 行式打印机 / 磁盘光盘
使用特性(用途)人机交互 / 存储 / 网络通信交互类慢;存储类快;通信类中等显示器键盘 / 移动硬盘 / 网卡、调制解调器
共享属性独占 / 共享 / 虚拟一段时间只给一个进程 / 宏观上多个进程同时用、微观上交替 / 用 SPOOLing 把独占设备虚拟成多台打印机 / 磁盘 / 虚拟打印机

设备控制器的组成

CPU 执行 I/O 指令 内存 DMA 时直接存取 系统总线 设备控制器(I/O 接口) 与 CPU 的接口 数据线 地址线 控制线 数据寄存器 控制寄存器 状态寄存器 I/O 逻辑 识别命令和地址 控制设备 与设备的接口 接口 1 接口 2 接口 n 设备 1 设备 2 设备 n 数据 / 状态 / 控制信号
一个控制器可以连多台设备,所以控制器要能“地址识别”:它有多个寄存器、多个设备接口,靠地址区分。
数据寄存器暂存要输入或输出的数据(数据缓冲,缓和 CPU 和设备的速度差)
控制寄存器CPU 写入命令和参数,控制器据此控制设备
状态寄存器记录设备当前状态(忙、就绪、出错),供 CPU 查询
控制器的功能接收识别命令、数据交换、报告设备状态、地址识别、数据缓冲、差错控制

寄存器怎么编址

统一编址(内存映射 I/O)

控制器寄存器占用内存地址空间的一部分,和内存单元一起编址。

  • 用普通访存指令(如 mov)就能读写寄存器,不需要专门的 I/O 指令;
  • 代价:占用一部分内存地址空间;访存指令和 I/O 操作看起来一样,要靠地址区分。

独立编址(专用 I/O 指令)

寄存器(I/O 端口)有一套独立的地址,叫端口号,和内存地址可以重叠。

  • 必须用专门的 I/O 指令(如 x86 的 IN、OUT)访问;
  • 好处:不占内存地址;指令清晰。代价:指令系统变复杂,I/O 指令通常功能较弱。
三 · I/O 控制方式

一路往下,CPU 被打扰得越来越少

四种方式比的都是同一件事:一次 I/O 里 CPU 要介入几次、数据要不要经过 CPU。

1. 程序直接控制(轮询)

CPU 向控制器发读命令;
/* 设备没就绪就一直查,CPU 空转 */
while (状态寄存器 != 就绪) ;
R = 数据寄存器;      /* 设备 → CPU 寄存器 */
mem[i++] = R;        /* CPU 寄存器 → 内存 */
/* 每读一个字都重复上面这些 */

实现简单。代价:CPU 与 I/O 完全串行,CPU 利用率极低。

2. 中断驱动

CPU 发出读命令后转去执行别的进程;设备把一个字准备好放进数据寄存器,就发中断。CPU 在每条指令周期末尾检查中断,响应后由中断处理程序把这个字读进 CPU 寄存器,再写入内存。

CPU 与 I/O 可以并行了。代价:每个字(字节)都要中断一次,保存和恢复现场开销大;数据仍然要经过 CPU。

3. DMA(直接存储器存取)

CPU 只在开始时把参数写进 DMA 控制器:读还是写、内存起址、传多少。之后 DMA 控制器自己在设备和内存之间一字一字搬,整块搬完才发一次中断。

CR 命令 / 状态寄存器存 CPU 发来的 I/O 命令、控制信息,或设备状态
MAR 内存地址寄存器输入时:数据要写到内存哪;输出时:从内存哪读
DR 数据寄存器暂存设备和内存之间正在传的那个数据
DC 数据计数器还剩多少字节没传,减到 0 就发中断

限制:每次只能传连续的若干块,读到内存里也必须连续存放;要读多段不连续的数据,CPU 得分别发多条 I/O 指令、处理多次中断。

4. 通道控制

通道是一种专门负责 I/O 的处理机。CPU 只需发一条 I/O 指令,指明通道程序在内存中的位置和要操作的设备;通道执行这段通道程序,把一组数据块(可以不连续)传完,才向 CPU 发中断。

和 CPU 的区别:通道指令类型单一,只能做 I/O;没有自己的内存,通道程序放在主存里,和 CPU 共享主存。

通道按信息交换方式分:字节多路通道(连多台低速设备)、数组选择通道(一次只服务一台高速设备)、数组多路通道(多台高速设备,按块轮流)。

四种方式对比

方式CPU 干预频率每次传送单位数据流向CPU 与 I/O 并行度
程序直接控制极高:全程盯着(忙等)字(字节)设备 → CPU 寄存器 → 内存串行
中断驱动高:每个字一次中断字(字节)设备 → CPU 寄存器 → 内存可并行(传数据时仍要 CPU)
DMA中:每块开始和结束时块(连续的一块或多块)设备 → 内存(经 DMA 控制器,不经 CPU)较高
通道低:一组块传完才中断一组数据块设备 → 内存(由通道控制)最高
四 · CPU 占用率计算(与计组联动)

先数“每秒 CPU 被叫几次”,再乘“每次花多久”

中断和 DMA 的题目长得不一样,但都套同一个框架。区别只在“一次”传多少数据:中断是一个字,DMA 是一整块。

CPU 占用率 = 每秒 CPU 介入次数 × 每次介入的 CPU 时间 ÷ 1 s 每秒介入次数 = 数据传输率 ÷ 每次传送的数据量(中断:一个字 / 字节;DMA:一个数据块)
每次介入的 CPU 时间 = 时钟周期数 ÷ 主频 = 指令条数 × CPI ÷ 主频

例 1 · 中断方式

主频 500 MHz,CPI = 5。外设数据传输率 0.5 MB/s,以 32 位为单位中断传送。中断服务程序 18 条指令,其他开销相当于 2 条指令。

每秒中断次数 = 0.5×106 B ÷ 4 B = 1.25×105 每次时钟周期 = (18 + 2) × 5 = 100 每秒占用周期 = 1.25×105 × 100 = 1.25×107 占用率 = 1.25×107 ÷ 5×108 = 2.5%

例 2 · DMA 方式

同一台机器,外设换成 5 MB/s,用 DMA,每块 5000 B,每次 DMA 的预处理 + 后处理共 500 个时钟周期。DMA 传送本身不占 CPU 时间。

每秒 DMA 次数 = 5×106 B ÷ 5000 B = 1000 每次时钟周期 = 500 每秒占用周期 = 1000 × 500 = 5×105 占用率 = 5×105 ÷ 5×108 = 0.1%

为什么 DMA 省这么多

如果 5 MB/s 的设备也用例 1 的中断方式:每秒中断 5×106 ÷ 4 = 1.25×106 次,占用 1.25×106 × 100 = 1.25×108 周期,占用率 25%。换成 DMA 只剩 0.1%:数据率涨了 10 倍,CPU 却只在每 5000 B 介入一次。

  • 速率里的 M 按题目约定:传输率一般按 106,存储容量一般按 220。题目没说时,看选项哪种能整除。
  • “其他开销”“预处理和后处理”都要加进每次的 CPU 时间;DMA 传送过程中的访存冲突一般不计入(题目另说明除外)。
  • 检查量纲:次数 / s × 周期 / 次 = 周期 / s,再除以主频(周期 / s)得到无量纲比例。
五 · I/O 软件层次

越往下越接近硬件,每层只和上下两层打交道

“某功能属于哪一层”是高频选择题。判据只有一条:涉及具体设备的硬件细节、且与中断无关的,在设备驱动程序;不涉及硬件、所有设备都要做的管理工作,在设备独立性软件。

用户层 I/O 软件用户态,库函数
  • 给用户提供与 I/O 交互的接口,库函数(如 printf)把请求翻译成系统调用;
  • 格式化:把二进制整数转换成 ASCII 字符串再输出;
  • SPOOLing 假脱机系统通常实现在这一层。
设备独立性软件与设备无关的软件;系统调用处理程序在这层
  • 向上提供统一的调用接口(read / write 等系统调用);
  • 设备保护:检查用户有没有权限访问这个设备(设备被当作特殊文件);
  • 差错处理(与具体设备无关的部分);
  • 设备的分配与回收;
  • 数据缓冲区管理;
  • 建立逻辑设备名 → 物理设备名的映射(查 LUT),并据此选择调用哪个驱动程序。
设备驱动程序每类设备一个,通常由厂商提供
  • 把上层的抽象命令(读第几块)翻译成这台设备能执行的具体操作;
  • 设置设备寄存器、写入命令、检查设备状态、启动设备;
  • 磁盘:由块号计算柱面号、磁头号、扇区号(磁盘物理地址);
  • 发出 I/O 命令后通常把自己阻塞,等中断唤醒。
中断处理程序与硬件紧密相关
  • I/O 完成时设备发中断:保存现场 → 分析中断原因 → 执行中断服务(从控制器读状态,判断是否正常完成,搬数据)→ 恢复现场;
  • 唤醒因等待这次 I/O 而阻塞的进程。
硬件设备控制器 + 设备

控制器执行命令、完成实际的数据传送,结束时发中断信号。

一次磁盘读请求走过的路径

用户程序调用 read
→
系统调用处理程序设备独立性软件:查权限、查缓冲
→
设备驱动程序算柱面 / 磁头 / 扇区,写控制器寄存器
→
设备(控制器)传数据,完成后发中断
→
中断处理程序唤醒等待的进程

请求自上而下,结果自下而上返回。常考的顺序题:用户程序 → 系统调用处理程序 → 设备驱动程序 → 中断处理程序。

应用程序 I/O 接口 · 阻塞与非阻塞

三类接口

  • 字符设备接口:get / put 系统调用,读写一个字符(键盘、打印机);
  • 块设备接口:read / write 读写一块,seek 修改读写指针(可寻址);
  • 网络设备接口:网络套接字 socket,socket / bind / connect / read / write。

驱动程序对下各不相同,对上要符合操作系统规定的统一接口,否则 OS 调不了它。

阻塞 I/O vs 非阻塞 I/O

  • 阻塞 I/O:进程发出请求后被阻塞,I/O 完成才被唤醒。例:从键盘读字符(scanf),没有输入就一直等;
  • 非阻塞 I/O:调用立即返回,进程继续执行,之后再查询或等待通知。例:往磁盘写数据,请求交出去就可以接着做事。

阻塞是说“进程等不等”,和“CPU 忙不忙等”是两件事:阻塞的进程让出 CPU,不占 CPU。

六 · 缓冲区管理

单缓冲和双缓冲,差在“传送 M 能不能和输入重叠”

缓冲区是内存中的一块区域(也可以是控制器里的寄存器)。它的规则只有一条:非空时不能往里冲入数据,只能取出;空了才能冲入,而且要冲满才能取出。下面的时间线全从这条规则推出来。

目的 1 · 缓和速度矛盾CPU 和 I/O 设备速度不匹配
目的 2 · 减少中断攒满一块再通知 CPU,降低中断频率,放宽对中断响应时间的要求
目的 3 · 粒度不匹配生产者按字符给、消费者按块要(或反过来)
目的 4 · 提高并行性CPU 算这一块时,设备可以同时读下一块
记号:T = 设备把一块数据输入缓冲区的时间,M = 从缓冲区传到用户区的时间,C = CPU 处理这块数据的时间。
单缓冲每块用时 = max(C, T) + M;双缓冲每块用时 = max(C + M, T) n 块总用时:单缓冲 = n × (max(C, T) + M) + min(C, T);双缓冲 = n × max(C + M, T) + min(C + M, T)。首块和末块的“启动 / 收尾”各多出一小段。
设备 → 缓冲区(T) 缓冲区 → 用户区(M) CPU 计算(C) 双缓冲中 1·A 表示第 1 块放在缓冲区 A

单缓冲为什么是 max(C, T) + M

  1. 设备输完一块(T),缓冲区满了,开始传到用户区(M)。
  2. M 期间:缓冲区正在被取,设备不能冲入;用户区正在被填,CPU 也不能算。M 和谁都不能重叠。
  3. M 结束后:缓冲区空了,设备开始输下一块(T);用户区满了,CPU 开始算(C)。两者并行,等较慢的那个结束,才能开始下一次 M。

所以稳定后每个周期 = max(C, T) + M。

双缓冲为什么是 max(C + M, T)

  1. 设备往 A 写的同时,B 里的数据可以往用户区传,所以 M 可以和 T 重叠了。
  2. 但用户区只有一个:M 要等上一块的 C 算完才能覆盖用户区,所以 M 和 C 仍然串行,合起来是 C + M。
  3. 设备这一侧每块要 T。两侧并行,谁慢谁决定节奏:max(C + M, T)。

推论:当 C ≥ T 时,两个公式都等于 C + M,双缓冲没有收益(瓶颈在 CPU)。

循环缓冲

多个等大缓冲区连成环。in 指针指向下一个可以冲入数据的空缓冲区,out 指针指向下一个可以取出数据的满缓冲区。本质是生产者—消费者问题的有界缓冲区。

缓冲池

全系统共用。三个队列:空缓冲队列、装满输入数据的队列、装满输出数据的队列。四种工作缓冲区:收容输入(hin)、提取输入(sin)、收容输出(hout)、提取输出(sout)。按需从队列摘取,用完挂回相应队列。

高速缓存 vs 缓冲区

高速缓存(Cache)缓冲区(Buffer)
相同点都介于高速设备和低速设备之间
存放的数据低速设备上某些数据的副本:Cache 里有的,低速设备上一定有低速设备和高速设备之间正在传递的数据,不一定在低速设备上有备份
目的存放高速设备经常要访问的数据;没命中时,高速设备还是要去访问低速设备高速设备和低速设备的通信都要经过缓冲区,高速设备永远不直接访问低速设备
七 · 设备分配与回收

分一台设备,要连着分到它的控制器和通道

一个通道连多个控制器,一个控制器连多台设备。数据要走通 “设备 → 控制器 → 通道 → 内存” 这条路,所以三样都分到了,这次分配才算成功。

全系统一张 每台设备一张 每个控制器一张 每个通道一张 SDT 系统设备表 打印机 1 表项 打印机 2 表项 磁盘表项 表项:类型、标识符、DCT 指针、驱动入口 DCT 打印机 1状态 / 等待队列 DCT 打印机 2 DCT 磁盘 COCT 控制器 1状态 / 等待队列 COCT 控制器 2 CHCT 通道 1状态 / 等待队列
高亮的是分配“打印机 1”时查表的路径:SDT → DCT → COCT → CHCT。两台打印机共用控制器 1,所以打印机 2 空闲也不代表能马上用:控制器 1 可能正忙。

分配步骤

  1. 根据进程请求的物理设备名查 SDT,找到该设备的 DCT;
  2. 查 DCT:设备忙,就把进程 PCB 挂到设备等待队列;不忙,分配设备;
  3. 由 DCT 找到 COCT:控制器忙,挂到控制器等待队列;不忙,分配控制器;
  4. 由 COCT 找到 CHCT:通道忙,挂到通道等待队列;不忙,分配通道。

三者都分到,才启动 I/O。回收时按相反方向释放,并唤醒各自等待队列里的进程。

改进:设备独立性(逻辑设备名)

上面的做法要用户写物理设备名,换一台设备程序就得改;某台忙时,同类的另一台空着也用不上。

改进:用户只写逻辑设备名(“打印机”),系统在 SDT 中找第一台该类型且空闲的设备分配,再在逻辑设备表 LUT 里登记:

逻辑设备名
→
物理设备名
→
驱动程序入口地址

LUT 可以全系统一张(逻辑设备名不能重名,适合单用户)或每个用户一张(登录时建立,多用户系统用)。

安全分配 vs 不安全分配

  • 安全分配:进程发出 I/O 请求后立即阻塞,直到 I/O 完成才唤醒。一个进程同时只占一台设备,破坏了“请求和保持”,不会死锁;代价是 CPU 与 I/O 对这个进程来说是串行的。
  • 不安全分配:发出请求后继续运行,还能再申请别的设备,只有请求的设备被占用时才阻塞。进程推进快,但可能死锁。

分配时考虑的因素

  • 设备固有属性:独占设备分给一个进程用到释放;共享设备可同时分给多个进程;虚拟设备靠 SPOOLing。
  • 分配算法:先来先服务、优先级高者优先。
  • 静态分配(作业开始前一次分齐,破坏请求和保持)/ 动态分配(运行中按需申请)。
八 · SPOOLing 假脱机技术

用磁盘冒充打印机,每个进程都“独占”一台

早年的脱机技术用一台外围控制机把慢设备的数据先抄到磁带上。SPOOLing 用软件模拟这件事:输入进程、输出进程代替外围控制机,磁盘上的输入井、输出井代替磁带。前提是有多道程序技术。

内存 磁盘 输入设备 输入缓冲区 输入井 用户进程只和井打交道 输入进程输入进程 输出井 输出缓冲区 打印机 输出进程输出进程
井在磁盘上(外存),缓冲区在内存里。用户进程读写的都是井,速度是磁盘的速度,不再受慢设备拖累。

共享打印机是怎么做到的

  1. 进程请求打印时,系统并不把打印机分给它,而是由输出进程在输出井里为它申请一块空闲区,把要打印的数据送进去;
  2. 再为它申请一张空白的打印请求表,填好后挂到假脱机文件队列上;
  3. 对进程来说打印已经“完成”,它可以继续运行;
  4. 打印机空闲时,输出进程从队首取一张请求表,把对应数据从输出井经输出缓冲区送到打印机。

特点和代价

  • 独占设备 → 共享设备:物理上打印机仍然一次只打一份,但多个进程可以同时“提交”;
  • 实现了虚拟设备:每个进程都觉得自己有一台打印机;
  • 提高了 I/O 速度:进程和井交换数据,缓和了 CPU 与慢速设备的矛盾;
  • 代价:占用磁盘空间和内存缓冲区,要有多道程序支持。是“空间换时间”。

不需要外围控制机,这是它和脱机技术的区别。

九 · 磁盘与固态硬盘

找磁道、等扇区转过来、再读,三段时间各有来源

结构

  • 盘面:每个盘片上下两面,每面一个磁头,所有磁头装在同一磁臂上共进退;
  • 磁道:盘面上的一圈同心圆;扇区:磁道再切成的一段,每个扇区存的数据量相同(内圈扇区面积小,密度大);
  • 柱面:所有盘面上半径相同的磁道组成一个柱面;
  • 磁盘地址 = (柱面号, 盘面号, 扇区号):先移磁臂到柱面,再激活盘面的磁头,最后等扇区转到磁头下。

为什么柱面号放最高位:读地址连续的块时,先把同一柱面的各个盘面读完,磁臂不用动。换成 (盘面号, 柱面号, 扇区号) 就要频繁移磁臂。

访问时间

Ta = Ts + 1/(2r) + b/(rN) Ts 寻道时间 = 启动磁臂时间 s + 跨越 n 条磁道 × 每条 m;
r 转速(转 / 秒),平均旋转延迟 = 转半圈 = 1/(2r);
b 要读的字节数,N 每磁道字节数,传输时间 = b/(rN)。
例:6000 转/分 = 100 转/秒 → 转一圈 10 ms 平均旋转延迟 = 10 ÷ 2 = 5 ms

旋转延迟和传输时间只和转速有关,OS 管不了。磁盘调度算法只优化寻道时间。

减少旋转延迟

  • 交替编号:读完一个扇区后磁头要一小段时间处理数据,这期间盘还在转。让逻辑相邻的扇区在物理上隔开几个,处理完正好转到下一个,不用多等一圈。
  • 错位命名:相邻盘面的 0 号扇区错开一个角度。读完一面最后一个扇区、切换磁头需要时间,切换好时下一面的 0 号扇区正好转到。

磁盘管理

  • 低级格式化(物理格式化):划分扇区,每个扇区 = 头 + 数据区 + 尾(含校验码 ECC);
  • 分区:把磁盘分成由若干柱面组成的分区(C 盘、D 盘);
  • 高级格式化(逻辑格式化):在分区上建立文件系统,写入根目录、空闲空间管理的初始数据结构(位示图、FAT 等);
  • 引导块:ROM 里只放很小的自举装入程序,完整的自举程序放在磁盘固定位置的启动块(引导块)上,有启动分区的叫启动盘 / 系统盘;
  • 坏块:简单磁盘由 OS 在 FAT 等结构里标记,对 OS 不透明;复杂磁盘由控制器维护坏块链表,低级格式化时用备用扇区替换坏块(扇区备用),对 OS 透明。

固态硬盘 SSD

基于闪存,没有机械部件,随机访问快。由闪存翻译层 FTL(把逻辑块号翻译成物理页地址,相当于磁盘控制器)和闪存芯片组成。一个块包含若干页。

  • 以页为单位读写,以块为单位擦除:块擦除后,其中每一页才能写一次。要改一个已写过的页,得先把整块里还有用的页复制到另一个已擦除的块,再擦除原块,所以写比读慢;
  • 闪存块反复擦写会磨损(有擦写寿命),所以要磨损均衡:
    • 动态磨损均衡:写入时优先选擦除次数少的新块;
    • 静态磨损均衡(更好):监测并迁移数据,让老旧的块多存以读为主的数据,较新的块承担更多写入。
十 · 磁盘调度算法

同一串磁道请求,六种排法走多远

横轴是磁道号,纵轴从上往下是访问顺序,折线就是磁头的轨迹。空心圆是磁头初始位置,方块是走到磁盘端点、没有服务任何请求的空行程拐点,虚线是 C-SCAN / C-LOOK 的返回段。

算法怎么走优点缺点
FCFS按请求到达顺序公平,实现简单请求分散时性能差,接近随机
SSTF每次选离当前磁头最近的请求平均寻道短只顾眼前(贪心),可能饥饿
SCAN沿当前方向服务,到磁盘端点才掉头不会饥饿,性能较好到端点的空行程;两端磁道响应慢、不均匀
C-SCAN只沿一个方向服务,到端点后直接回到另一端,返回途中不服务各磁道等待时间更均匀返回的空行程
LOOKSCAN 的改进:到当前方向最远的请求就掉头省掉到端点的空行程仍然两端不均匀
C-LOOKC-SCAN 的改进:到最远请求后,直接回到另一侧最远的请求均匀,空行程更短仍有返回段
返回段计不计入移动距离:本页默认按王道课程的算法计入。例如磁头在 100、向增大方向、磁道 0~199 时,C-SCAN 总移动 = (199 − 100) + (199 − 0) + (最后服务的磁道 − 0),返回的 199 条磁道也算。个别题目会说明“返回时间忽略不计”,那时把下面的开关关掉。另外,有的题目说 SCAN 却按“到最远请求就掉头”计算(实际是 LOOK):题目给了磁道范围、明确到端点,就按 SCAN;选项对不上时,再按 LOOK 算一遍。

六种算法对比(当前参数)

SSTF 遇到两个请求距离相等时,本模拟器优先沿当前移动方向走。

十一 · 易错速记 & 速查表

选择题直接对表

DMA 不是“完全不用 CPU”块的开始(设置 MAR、DC 等)和结束(中断处理)都要 CPU;中间传送不经过 CPU。
中断响应时机 vs DMA 响应时机中断在一条指令执行结束时响应;DMA 请求在每个机器周期(存取周期)结束后就能响应,更快。
通道没有自己的内存通道程序放在主存里,和 CPU 共享主存;通道是“弱化的”处理机,只能执行 I/O 指令。
块设备可寻址,字符设备不可寻址磁盘是块设备,键盘、打印机、鼠标是字符设备。
SPOOLing 在哪井在磁盘,缓冲区在内存;它把独占设备改造成共享设备,打印机物理上还是一次只打一份。
缓冲的规则非空不能冲入,满了才能取出。单缓冲 max(C, T) + M,双缓冲 max(C + M, T);C ≥ T 时两者相等。
Cache 和缓冲区Cache 里的是副本,低速设备上一定有;缓冲区里的数据低速设备上不一定有。
三张表都要分到设备、控制器、通道都分配成功才能启动 I/O;设备空闲不代表控制器或通道空闲。
调度只管寻道旋转延迟 1/(2r) 和传输时间 b/(rN) 只与转速有关;交替编号、错位命名是从磁盘地址布局上减少旋转延迟。
谁会饥饿SSTF 可能饥饿;SCAN 系列不会。SSTF、SCAN、C-SCAN 都可能“磁臂黏着”(反复请求同一磁道),FCFS 不会。
SCAN 和 LOOKSCAN 到端点才掉头,LOOK 到最远请求就掉头。服务完最后一个请求就停,不必再走到端点。
SSD 的读写单位按页读写,按块擦除;写比读慢;磨损均衡分动态和静态,静态更好。

I/O 软件层次 · 功能归属速查

功能 / 操作属于哪一层判断理由
SPOOLing 假脱机用户层软件用户进程级的服务,建立在设备独立性软件之上
把二进制整数转成 ASCII 再打印用户层软件库函数做的格式化,与设备无关也不需要内核
库函数 printf / scanf用户层软件把请求翻译成系统调用
统一的 read / write 接口(系统调用处理)设备独立性软件对所有设备一样
设备保护(检查用户有无权限)设备独立性软件不涉及硬件细节,所有设备都要做
逻辑设备名 → 物理设备名(LUT)设备独立性软件“设备独立性”这个名字的来源
设备的分配与回收设备独立性软件管理工作,与具体设备型号无关
缓冲区管理设备独立性软件所有设备都要用
与设备无关的差错处理设备独立性软件通用的错误报告和处理
由块号计算柱面号、磁头号、扇区号设备驱动程序要知道这块磁盘的具体几何参数
向设备寄存器写命令、设置参数设备驱动程序涉及具体硬件,且与中断无关
检查设备状态、启动设备设备驱动程序涉及具体硬件
保存现场、分析中断原因、恢复现场中断处理程序中断相关
I/O 完成后唤醒被阻塞的进程中断处理程序由完成中断触发

四种 I/O 控制方式速查

方式中断次数传送单位数据经过 CPU?CPU 与 I/O典型用途
程序直接控制无中断(CPU 轮询)字是串行早期简单系统
中断驱动每个字一次字是并行键盘等字符设备
DMA每块一次(开始预处理 + 结束中断)块否,设备 ↔ 内存直接传并行度较高磁盘等块设备
通道一组块一次一组块否,通道执行通道程序并行度最高大型机多设备