本文主要内容来自 SpriCoder的博客,更换了更清晰的图片并对原文的疏漏做了补充和修正。
设备管理概述
I/O 系统、设备与操作
I/O 系统是 I/O 设备及其接口线路、控制部件、通道和管理软件的统称。
I/O 设备又称为外围设备或外部设备,简称外设
- 用于计算机系统与外部世界(如用户、其他计算机或设备)的信息交换或存储
- 把外界信息输入计算机,把计算结果从计算机中输出,完成计算机之间的通信或人机交互。
I/O 操作:内存和设备介质之间的信息传送操作
- 影响计算机的通用性和可扩充性
- 计算机系统综合处理能力及性价比的重要因素
I/O 设备的分类
按信息传输方向(I/O 操作特性)划分
- 输入设备:将外界信息输入计算机,例如:键盘,鼠标,扫描仪等
- 输出设备:将计算结果输出,例如:显示器,打印机等
- 输入输出设备:既可以输入信息,也可以输出信息,例如:磁盘驱动器,网卡等
按交互功能划分
- 人机交互设备:用于用户与计算机之间的交互通信,例如:鼠标,键盘,显示器等
- 存储设备:持久性地存储大量信息并快速检索,例如:磁盘驱动器,光盘驱动器等
- 机机通信设备:用于计算机和计算机之间的通信,例如:网卡,调制解调器等
按设备管理(I/O 信息交换单位)划分
- 字符设备:
- 以字符为单位进行信息交换,发送或接收一个字符流。
- 严格依赖新消息的物理位置进行定位和读写。
- 输入输出设备、人机交互设备大多是字符设备,例如鼠标、显示器等。
- 块设备:
- 以固定大小的数据块(块是存储介质上连续信息组成的一个区域)进行信息交换。
- 存取任何一个物理块所需的时间几乎不依赖于此信息所处的位置。
- 存储设备通常为块设备,例如磁盘驱动器等。
- 网络设备:用于与远程设备通信的设备
- 机机通信设备为网络设备,例如网卡等
- 网络设备可以抽象为传送字符流的特殊字符设备,也可以抽象为传送连续小块数据的块设备
设备管理的目标
- 解决设备和 CPU 速度的不匹配,使主机和设备并行工作,提高设备使用效率
- 对设备进行抽象,屏蔽设备的物理细节和操作过程,配置驱动程序,提供统一界面,供用户或高层软件使用
- 抽象为裸设备:不被操作系统直接管理,由应用程序读写,I/O 效率更高
- 抽象为设备文件:文件系统中的节点,统一管理。文件系统:按名存储、提高文件的标准化操作,设备管理转换为文件管理。
设备管理的功能
- 设备中断处理:中断最初来源于设备
- 缓冲区管理
- 设备的分配和去配:合适给进程分配进程以及回收
- 设备驱动调度
- 实现虚拟设备
设备管理的层次
- I/O 硬件:
- I/O 设备及其接口线路
- 控制部件
- 通道
- I/O 软件:
- 系统 I/O 软件
- 用户空间 I/O 软件
I/O 控制方式
设备控制器(偏向硬件部分)
为达到模块化和通用性的设计目标,通常将 I/O 设备中的机械部件和电子部件分开处理:
- 机械部件是指设备本身
- 电子部件称为设备控制器或适配器
设备控制器又称为设备适配器、I/O 控制器、I/O 控制接口,简称 I/O 模块或 I/O 接口。
操作系统与控制器交互,而非与设备交互:
- 多数微型和小型计算机系统通过单总线模式来交互
- 大中型计算机采用多总线结构和多通道方式来交互。
设备控制器具体控制设备进行 I/O,将串行的位流装配成字节,存入控制器内部的缓冲区形成字节块,在校验和确认无错后,这块数据将被复制进入内存。
设备控制器的功能
设备控制器是 CPU 与设备之间的接口:
- 接收和识别 CPU 或通道发来的命令,例如磁盘控制器可以接受读写等操作
- 实现数据交换:包括设备和控制器之间的数据传输,且通过数据总线或通道,控制器和内存之间传输数据。
- 发现和记录设备及自身的状态信息,供 CPU 处理使用
- 识别设备地址,当连接多台设备时
设备控制器的组成部分(例)
- 状态/控制寄存器
- 数据缓冲寄存器
- 地址译码器和 I/O 控制逻辑
- 外设接口控制逻辑
轮询方式(程序直接控制方式)
流程
- 处理器向控制器发送一个 I/O 命令
- 如果设备未就绪,则重复测试过程,直至设备就绪
- 执行数据交换:CPU 从 I/O 接口(数据寄存器)读取一个字,然后用存储指令保存到内存。
- 等待 I/O 操作完成后,才可以继续其它操作
涉及指令
- 查询指令:查询是否就绪
- 读写指令:就绪执行数据交换
- 转移指令:未就绪转向查询
特点和评价
- 处理 I/O 请求会终止原程序的执行,浪费时间
- CPU 需要等待 I/O 设备就绪
- CPU 需要参与数据传送
- 总而言之,CPU 和设备只能串行工作,效率低下
中断方式
流程
- 处理器向控制器发出一个 I/O 命令,然后继续执行后续指令
- 如果该进程不需要等待 I/O 完成,后续指令可以仍是该进程中的指令。
- 否则,该进程在这个中断上挂起,处理器执行其他工作
- 控制器检查设备状态,按照 I/O 命令要求完成相应 I/O 操作,就绪后发起中断
- CPU 响应中断,转向中断处理程序
- 中断处理程序,执行数据读写操作
- 退出中断处理程序,返回发生中断前的执行状态。
特点和评价
- 响应中断后会终止原程序的执行
- CPU 不需要等待 I/O 设备就绪
- CPU 需要参与数据传送,但是缓冲区满就要发起中断,会消耗较多 CPU 时间,如果有过多的设备可能会导致 CPU 来不及响应或数据丢失的情况。
- 总而言之,CPU 和设备部分并行操作,效率有所提高
直接存储器访问(DMA)方式
DMA 模块
DMA 模块:模仿处理器来控制主存和设备控制器之间的数据交换。
DMA 方式中,内存和设备之间有一条数据通路成块地传送数据,无需 CPU 参与。
DMA 模块完成如上描述的数据传输任务。
组成结构:
- 内存地址寄存器:存放内存中需要交换数据的地址,DMA 传送之前由程序送入首地址;DMA 传送过程中,每次交换数据都把地址寄存器的内容加 1
- 字计数器:记录传送数据的总字数,每次传送一个字就把字计数器减 1。
- 数据缓冲寄存器或数据缓冲区:暂存每次传送的数据。
- 设备地址寄存器:存放 I/O 信息的地址,如磁盘的柱面号、磁头号、扇区号。
- 中断机制和控制逻辑: 用于向 CPU 提出 I/O 中断请求及保存 CPU 发来的 I/O 命令,管理 DMA 的传送过程。DMA 与内存之间采用字传送,DMA 与设备之间可能是字位或字节传送,所以 DMA 中要设置数据移位寄存器、字节计数器等硬件逻辑。
为什么控制器从设备读取数据后不立即送进内存,而是使用内部缓冲区?
一旦磁盘开始读数据,其读出速度是恒定的,无论控制器怎样就要接收数据,如果控制器立即送进内存,则需要系统总线的控制权,但是可能会等待,因此需要内部缓冲区,使得 DMA 操作启动前不需要总线。
流程
- 处理器向 DMA 模块发出 I/O 命令
- 处理器继续执行其它工作,DMA 模块负责传送全部数据
- 数据传送结束后,DMA 中断处理器
特点和评价
- CPU 不会终止原程序的执行,不需要发生中断,提高 CPU 资源利用率。
- CPU 只在数据传送的开始和结束时参与。
- 开始时,CPU 需要对 DMA 模块进行初始化。
- 结束时,CPU 响应中断,但不必保存现场。
- 优点:线路简单、价格低廉,适用于小型和微型计算机的快速设备。
- 缺点:DMA 窃取时钟周期,功能不够强不能满足复杂的 I/O 操作要求。
DMA 方式中的周期窃取
当 DMA 和 CPU 同时经总线访问内存时,CPU 总是将总线的占有权让给 DMA 一个或几个主存周期,一般是 1 个存取周期,让设备和内存之间交换数据。
周期窃取对延迟 CPU 与主存的数据交换影响不大:
- 数据传送过程是不连续的和不规则的
- CPU 大部分情况下与 Cache 进行数据交换,直接访问内存较少
小结:I/O 控制方式的演化
- 采用轮询方式的设备控制器:CPU 需要等待设备就绪,且参与数据传送
- 采用中断方式的设备控制器:CPU 无需等待设备就绪,但响应中断后参与数据传送:通过 DMA 直接控制存储器
- CPU 在数据传送开始和结束时:参与,与主存进行数据交换时不参与
CPU 作用 | 等待设备 | 数据传送 |
---|---|---|
轮询方式 | 需要 | 参与 |
中断方式 | 不需要 | 参与 |
DMA 方式 | 不需要 | 不参与 |
I/O 通道(第四种,更高级)
I/O 通道描述
I/O 通道又称为通道控制器、I/O 处理器,用于完成逻辑上独立的 I/O 任务,适用于中大型计算机系统,用于实现内存与外设(而不是 CPU 与外设)之间的信息传输。
设备控制器包含自身专用的处理器和通道程序(由一系列通道指令组成),自成体系,使得 CPU 与通道高度并行,实现通道和 CPU 并行操作,通道之间并行操作,设备之间并行操作。
- I/O 指令不再由处理器执行,而是存在主存中,由 I/O 通道所包含的处理器执行
- 采用主存,通道,控制器,设备的四级连接,实施三级控制,可控制多台同类或不同类的设备
- 一个 CPU 通常连接多个通道,通过 I/O 指令控制
- 一个通道可以连接若干控制器,通过执行通道命令控制
- 一个控制器可以连接若干设备,通过动作序列控制
DMA 和 I/O 通道不同点:DMA 中,每一个 I/O 指令只能读写一个数据块,而通道可以一次面向不同的多个数据块。
I/O 通道的工作流程
- CPU 在执行主程序时遇到 I/O 任务,启动指定通道(通过通道程序地址字 CAW)上选址的设备。
- 启动成功,通道开始控制设备进行操作,此时 CPU 继续执行其他任务,直到 I/O 操作完成。
- 通道发出 I/O 操作结束中断,处理器相应并停止当前工作,转向处理 I/O 操作结束事件。
CPU 与通道并行工作。
带有局部存储器的 I/O 通道
- 相当于一台自治的计算机:I/O 指令存储在控制器自带的局部存储器中,并由 I/O 通道所包含的处理器执行
- 可以控制大量的 I/O 设备,同时最小化 CPU 的干涉
- 常用于交互式终端通信,负责包括控制终端在内的大部分任务
I/O 发展对总线的影响
单总线
将 CPU、主存和 I/O 模块连接到同一组总线上
优点:结构简单,易于扩充
缺点:
- 主存需要和 I/O 模块共用总线
- 设备增多会造成总线变长,进而增加传输时延
- 无法适用于大量高速设备
传统的三级总线(例)
- 主存和 Cache 通过主存总线传送数据,CPU 和 Cache 之间存在局部总线;
- 主存总线和扩展总线上的 I/O 设备之间传送数据通过扩展总线接口缓冲
- 优点:主存与 I/O 之间的数据传送与处理器的活动分离;可以支持更多的 I/O 设备
- 缺点:不适用于 I/O 设备数据速率相差太大的情形
采用南北桥的多级总线(例)
- 通过存储总线、PCI 总线、E(ISA) 总线分别连接主存、高速 I/O 设备和低速 I/O 设备,距离 CPU 比较近的北桥控制器
- 优点:可以支持不同数据速率的 I/O 设备
采用 I/O 通道的多级总线(例)
- 支持 CPU、主存和多个 I/O 通道之间的数据传送
- 支持 I/O 通道和 I/O 控制器,以及 I/O 控制器和设备之间的数据传送
I/O 软件的实现
I/O 软件
设计目标:
- 高效率:改善设备效率,尤其是磁盘 I/O 操作的效率,有很大的影响
- 通用性:用统一的标准来管理所有设备
设计思路:把软件组织成层次结构,低层软件用来屏蔽硬件细节,高层软件向用户提供简洁、友善的界面。
主要考虑的问题:
- 设备无关性:编写访问文件的程序与物理设备无关
- 出错处理:低层软件能处理的错误不让高层软件感知
- 同步/异步传输:支持阻塞和中断驱动两种工作方式
- 同步:如果要同步就需要做等待,增加延迟
- 异步:可以不等待,提供并行度(不等是有前提的,运行进程的后续操作不可以依赖 I/O 操作的结果)
- 缓冲技术:建立数据缓冲区,匹配数据的到达率与离去率,提高吞吐率
I/O 软件的层次结构
为了解决 I/O 软件主要考虑的问题,我们将其划分为如上四个层次结构
I/O 中断处理程序
- I/O 中断处理程序位于操作系统底层,与硬件设备密切相关,与系统其余部分尽可能少地发生联系
- 进程请求 I/O 操作时,通常被挂起,直到数据传输结束后并产生 I/O 中断时,操作系统接管 CPU 后转向中断处理程序
- 当设备向 CPU 提出中断请求时,CPU 响应请求并转入中断处理程序
I/O 中断处理程序的功能
检查设备状态寄存器内容,判断产生中断的原因,根据 I/O 操作的完成情况进行相应的处理:
- 如果数据传输有错,向上层软件报告设备的出错信息,实施重新执行
- 如果正常结束,唤醒等待传输的进程,使其转换为就绪态
- 如果有等待传输的 I/O 命令,通知相关软件启动下一个 I/O 请求
设备驱动程序
- I/O 设备驱动程序包括与设备密切相关的所有代码
- I/O 设备的功能是从独立于设备的软件中接收并执行 I/O 请求:
- 把用户提交的逻辑 I/O 请求转化为物理 I/O 操作的启动和执行,如设备名转换为端口等
- 监督设备是否正确执行,管理数据缓冲区,进行必要的纠错处理
- 某些控制器一次只能接受一条命令(DMA),有些控制器可以接受一串命令后执行(通道)
设备驱动程序的功能
- 设备初始化:在系统初次启动或设备传输数据时,预置设备和控制器以及通道状态
- 执行设备驱动例程:
- 负责启动设备,进行数据传输
- 对于具有通道方式,还负责生成通道指令和通道程序,启动通道工作
- 调用和执行中断处理程序:负责处理设备和控制器及通道所发出的各种中断
设备驱动程序的处理方式 *
- 阻塞自己:命令开始执行时,进程阻塞自己,直到昨晚才解除阻塞。
- 无须阻塞:很快就可以完成,比如滚屏。
- 无论哪种,操作完成后都需要记性数据传输正确性校验,如果有错则报告。
设备驱动程序的层次
每个设备驱动程序只处理一种设备,或者一类紧密相关的设备
设备驱动程序分为整体驱动程序和分层驱动程序:
- 整体驱动程序直接向操作系统提供接口和控制硬件。适用于功能简单的驱动程序,效率较高,但较难迁移
- 分层驱动程序将驱动程序分成多层,放在栈中,系统接到 I/O 请求时先调用栈顶的驱动程序,栈顶的驱动程序可以直接处理请求或向下调用更低层的驱动程序,直至请求被处理。适用于功能复杂、重用性要求较高的驱动程序,结构清晰且便于移植,但会增加一部分系统开销
独立于设备的 I/O 软件
执行适用于所有设备的常用 I/O 功能,并向用户层软件提供一致性接口
设备命名
通过路径名寻址设备
设备保护
- 检查用户是否有权访问所申请设备
- 多数大中型计算机系统中,用户进程对 I/O 设备的直接访问是绝对禁止的,I/O 指令被定义为特权指令,使用系统调用方式访问。
- 设备文件依赖于 inode 实现,文件目录并不能区分文件名是代表磁盘文件还是设备文件,但是 inode 号是不同的。
- 磁盘 inode 包含指向数据块的指针。
- 设备文件 inode 包含指向内核设备驱动程序的指针。
提供与设备无关的数据单位
- 操作系统会为磁盘分配记录空闲块的表或位示图。
- 不同磁盘的扇区大小可能不同,独立于设备的 I/O 设备软件屏蔽这个事实,向高层软件提供统一的数据尺寸:通过将若干扇区合并成逻辑块——簇,簇大小相同。
- 使得字符设备可以对一个字符操作,也可以对更大单位的数据操作。
缓冲技术
通过缓冲消除填满速率和清空速率的影响:
- 网络上数据需要分析检查才知道去哪里。
- 有些设备有严格时间约束,比如数字音频设备。
块设备和字符设备都需要缓冲技术:
- 块设备:磁盘读写以块为单位,应用程序以任意大小单元处理设备,如果应用程序读写长度和位置不是完整扇区,则需要使用缓冲区来缓冲。
- 字符设备:字符设备提供数据速度快于或慢于应用程序消耗数据的速度。
缓冲设计大量复制操作,对 I/O 性能有较大开销。
设备分配和状态跟踪
根据设备物理特性,操作系统制订分配策略:
- 静态分配
- 动态分配
- 虚拟分配
错误处理和报告
- 错误应该在尽可能接近硬件的地方处理,想办法纠正和解决。
- 未能解决,交给驱动程序处理,比如是磁盘块受损无法读写。
- 驱动程序无法处理的错误,交给独立于设备的 I/O 软件报错。
用户空间的 I/O 软件
库函数:
- 一小部分 I/O 软件不在操作系统中,是与应用程序链接在一起的库函数,甚至完全由运行于用户态的程序组成
- 系统调用通常由库函数封装后供用户使用,封装函数只是将系统调用所用的参数放在合适位置,然后执行访管指令来陷入内核,再由内核函数实现真正的 I/O 操作
SPOOLing 软件:
在内核外运行的系统I/O 软件,采用预输入、缓输出和井管理技术,是多道程序设计系统中处理独占型设备的一种方法,通过创建守护进程和特殊目录解决独占型设备的空占问题
I/O 操作应执行的步骤,以读操作为例 *
- 应用进程对已打开文件的文件描述符执行读系统调用(库函数)。
- 独立于设备的 I/O 软件检查参数是否正确,若正确,检查高速缓存中有无要读取的信息块
- 若有,从缓冲区直接读至用户区,完成 I/O 请求。
- 若数据不在缓冲区,执行物理 I/O 操作,独立于设备的 I/O 软件将设备的逻辑名转换成物理名,检查对设备操作的许可权,将 I/O 请求排队,阻塞应用进程且等待 I/O 操作完成。
- 内核启动设备驱动程序,分配存放读出块的缓冲区,准备接收数据并向设备控制寄存器发送启动命令,或建立 DMA 传输,启动 I/O。
- 设备控制器操作设备,执行数据传输。
- 当采用 DMA 控制器控制数据传输时,一旦传输完成,硬件产生 I/O 结束中断。
- CPU 响应中断,转向磁盘中断处理程序。它检查中断产生原因和设备的执行状态,若设备有错,向设备驱动程序发信号,检查是否能重复执行,如果允许,重发启动设备命令,再次传输;否则,向上层软件报告错误。若设备 I/O 正确完成,将数据传输到指定的用户进程空间,唤醒阻塞进程并将其放人就绪队列;然后,系统检查有无 I/O 请求在排队,若有,再启动设备,继续传输。至此,中断处理完成且返回,将成功或失败的信息逐层向上报告。
- 当应用进程被再次调度执行时,从 I/O 系统调用的断点处恢复执行。
I/O 缓冲
目的:
- 解决CPU 与设备之间速度不匹配的矛盾,协调逻辑记录大小和物理记录大小不一致的问题
- 减少 I/O 操作对 CPU 的中断次数
- 放宽对 CPU 中断响应时间的要求
- 提高 CPU 和设备的并行性
缓冲区:在内存中开辟的存储区,专门用于临时存放 I/O 操作的数据
操作:
- 写操作:先向系统申请一个输入缓冲区,将数据送至缓冲区,直到装满或需要写存储,待适当时候系统将缓冲区内容写到设备上
- 读操作:先向系统申请一个输出缓冲区,系统将设备上的物理记录读至缓冲区,根据要求将当前所需要的数据从缓冲区中读出并传送给进程
单缓冲
每当应用程序发出 I/O 操作时,操作系统在主存(内存)的系统区中开设一个缓冲区
工作机制
输入:将数据读至缓冲区,系统将缓冲区数据送至用户区,应用程序对数据进行处理;如此往复,系统读入后续的数据
输出:把数据从用户区复制到缓冲区,再将数据输出后,应用程序继续请求输出
如果希望输入的数据被加工后再输出,则需要双缓冲。
性能计算 *
读取到缓冲区需要时间 T,从缓冲区到用户区耗时 M,应用程序计算耗时 C
- 无缓冲:T + C
- 单缓冲:max(C, T) + M,M << C, T
双缓冲
操作系统在主存的系统区中开设两个缓冲区
工作机制
输入:
- 设备首先将数据输入缓冲区 1,系统再从缓冲区 1 把数据传到用户区,供应用程序处理,同时从设备数据传送到缓冲区 2
- 当缓冲区 1 为空,则再次从设备读出数据到缓冲区 1,将缓冲区 2 的数据传送到用户区,供应用程序处理,同时从设备数据传送到缓冲区 1
- 仅当两个缓冲区全为空,并且进程还要提取数据时等待。
输出:
- 第一张卡片读入缓冲区 1,在打印缓冲区 1 中数据的同时,又把第二张卡片读入缓冲区 2。
- 缓冲区 1 打印完毕时,缓冲区 2 也刚好输入完毕,让读卡机和打印机交换缓冲区。这样,I/O 设备就能够处于并行工作状态。
性能分析
- C < T,输入比计算慢:M << T,因此一块数据的传输和处理时间为 T,即 max(C, T)
- C > T,输入比计算快:计算完成后,需要用 M 的时间来传输,所以一块数据的传输和处理时间为 C + M,即 max(C, T) + M
循环缓冲
多缓冲组成的循环缓冲技术:解决了上面的 C 和 T 时间不匹配而导致的缓冲区被抽空或塞满的问题(解决设备和进程速度不匹配的问题)
操作系统分配一组缓冲区,每个缓冲区度有指向下一个缓冲区的链接指针,最后一个缓冲区指针指向第一个缓冲区,组成循环缓冲,缓冲区的大小等于物理记录的大小,多缓冲的缓冲区是系统的公共资源,可供进程共享并由系统统一分配和管理。缓冲区用途可分为输人缓冲区、处理缓冲区和输出缓冲区。为了管理各类缓冲区,执行各种操作,必须设计专门的软件,这就是缓冲区自动管理系统。
补充:数据缓冲区高速缓冲的实现思想(P267)
设备独立性
- 问题:作业执行前对设备提出申请时,指定某台具体的物理设备会让设备分配变得简单,但如果所指定设备出现故障,即便计算机系统中有同类设备也不能运行
- 设备独立性:用户通常不指定物理设备,而是指定逻辑设备,使得用户作业和物理设备分离开来,再通过其它途径建立逻辑设备和物理设备之间的映射,包含两种:
- 静态重定位
- 动态重定位:当前多用,对硬件要求更高一些。
- 设备管理的功能就是将逻辑设备名转换为物理设备名,为此系统需要提供逻辑设备名和物理设备名的对应表以供转换使用。
- 逻辑设备号由用户定义。
- 物理设备号由系统规定,不可修改。
- 微型计算机的操作系统中不一定支持设备独立性。
设备独立性的优点
- 应用程序与具体物理设备无关,系统增减或变更设备时不需要修改源程序
- 易于应对I/O 设备故障,提高系统可靠性
- 增加设备分配的灵活性,更有效地利用设备资源,实现多道程序设计
设备分配方式
设备管理的功能之一就是为计算机系统所接纳的每个计算任务分配所需要的外部设备。
设备的物理特性
- 独占设备:一次只能由一个进程独占使用;
- 共享设备:可以让多个进程同时使用的设备,其管理工作主要是驱动调度和实施驱动,一般不必分配;
- 虚拟设备:将独占设备改为共享设备。
分配方式
- 静态分配:进程运行前申请,实现简单,能够防止系统发生死锁,但会降低设备利用率,独占型设备多选
- 动态分配:进程随用随申请,提高设备利用率,但是对于打印机等独占型设备使用动态分配可以显著提高设备利用率。
联系 PV 操作 *
- 操作过程:\(... P(S_1) ... D(S_1)...\)
- \(P(S_1)\):申请 \(D_1\) 设备
- 然后在临界区内互斥使用该设备,独占式
- \(V(S_1)\):归还 \(D_1\) 设备
- \(S_1\) 代表设备 \(D_1\) 资源,P 操作前和 V 操作后都是代码
- 存在死锁风险
设备分配的数据结构
设备类表
- 每类设备对应于设备类表的中的一栏
- 包括:设备类、总台数、空闲台数、设备表起始地址等
- 支持设备独立性时才会使用
设备表
- 每类设备都有各自的设备表,用来登记这类设备中的每台物理设备
- 包括:物理设备名(号)、逻辑设备名(号)、占有设备的进程号、是否分配、好/坏标志等
通道结构系统 *
需要对通道、控制器和每台物理设备进行管理和控制,必须设置系统设备表、通道控制表、控制器控制表和设备控制表。
- 整个系统建立一张系统设备表,记录系统配置的所有物理设备的情况,每台物理设备占有一栏,包括设备类型、台数、设备号、设备控制表指针等。
- 对于通道控制表、控制器控制表和设备控制表,每个通道、控制器、设备各设置一张,分别记录各自的地址(标识符)、状态(忙/闲、已分配/未分配)、等待获得此部件的进程队列指针及一次分配后相互链接的指针,以备分配和执行 I/O 操作时使用。
磁盘的物理结构
- 磁盘是一种直接存取存储设备,又称为随机存取存储设备,每条物理记录都有明确的位置和唯一的地址。
- 按照三维坐标进行随机存储。
磁盘的组成
- 磁盘由多个盘片组成,每个盘片被划分为多个同心圆结构的磁道,每个盘片的两面都是可以数据的
- 不同盘片上位于相同位置的磁道构成的圆柱体称为柱面
- 每个磁道分为固定多个或不等个数的扇区:为了对大量扇区寻址,操作系统将相邻的扇区组合成簇存储文件
物理块(扇面)在磁盘上的三维地址(磁头号,柱面号,扇区号)
盘面号也被叫做磁头号
磁道号也被叫做柱面号
区别:“0 面 0 道 1 扇区”中的“面”是指磁头,不是柱面。面和道都是 0 开始,扇区是从 1 开始。
磁盘读写数据
读写数据时,磁头必须定位到指定的磁道上的指定扇区的开始处
过程:
- 寻道:控制移动臂到达指定柱面,选择磁头号,所用时间被称为查找时间
- 旋转:等待要读写的扇区旋转到磁头下,所用时间被称为搜索延迟
- 数据传送
高效的外存储都是用磁盘来完成的。
磁盘存取时间
磁盘完成数据读写所需要的时间:是寻道时间、旋转延迟、传送时间的总和
\[ T_a = T_s + \frac{1}{2r} + \frac{b}{rN} \]
- \(T_a\):(平均)存取时间
- \(T_s\):寻道时间
- \(r\):磁盘旋转速度(单位:转/秒)
- \(b\):要传送的字节数
- \(N\):一个磁道中的字节数
磁盘的驱动调度 *
磁盘调度策略
磁盘可能同时接收到若干 I/O 请求:如果随机选择并响应 I/O 请求,可能得到最坏的性能
驱动调度:
- 系统采用一种调度策略,能够按最佳次序执行要求访问磁盘的多个 I/O 请求
- 能减少为若干 I/O 请求服务所需要消耗的总时间
调度策略包括:
- 旋转调度
- 移臂调度
移臂调度
目的:使移动臂的移动时间最短,从而减少寻道总时间
FCFS 先来先服务算法
- 移臂距离大,性能不好,移动臂是随机移动,寻道性能较差
- 按顺序处理请求,对所有进程公平
最短查找时间优先(最小短距离法) SSTF,Shortest Service Time First
- 先执行查找时间最短的请求,具有较好的寻道性能
- 存在“饥饿”现象:距离比较远的难以被满足
- 选择使磁头臂从当前位置开始移动最少的磁盘 I/O 请求,因此 SSTF 策略总是选择导致最小寻道时间的请求,总是选择最小寻道时间并不能保证平均寻道时间最小,但是,它的性能比 FCFS 更好
SCAN 扫描算法(双向扫描算法)
移动臂每次向一个方向移动,遇到最近的 I/O 请求便进行处理,到达最后一个柱面后再向相反方向移动
对最近扫描所跨越区域的请求响应较慢
和电梯调度算法的不同:碰壁才会折返
分布扫描算法 N-step-SCAN
进程重复请求同一磁道会垄断整个设备造成磁头臂的粘性,采用分步扫描可避免这类问题
- 把磁盘 I/O 请求队列分成长度为 N 的子队列,按照 FIFI 处理每一个子队列,每个子队列内部使用扫描算法
- 在处理一个队列时,新请求必须添加到其他某个队列中
- 处理完一个子队列后再服务下一个队列
如果在扫描的最后剩下的请求数小于 N,则它们全部将在下一次扫描时处理
- 当 \(N \rightarrow \infty\) 时,N-step-SCAN 的性能接近 SCAN
- 当 \(N = 1\) 时,实际上是 FIFO
LOOK 电梯调度算法
- 无请求时移动臂停止不动,有请求时按电梯规律移动
- 每次选择沿移动臂的移动方向最近的柱面
- 如果当前移动方向上没有但相反方向有请求时,改变移动方向
C-SCAN 循环扫描(单向扫描)
- 把扫描限定在一个方向
- 当访问到沿某个方向的最后一个磁道时,磁头臂返回到磁盘相反方向磁道的末端,并再次开始扫描
补充:后进先出(LIFO,Last-in, first-out)
- 在事务处理系统中,把设备资源提供给最近的用户,会导致磁头臂在一个顺序文件中移动时移动得很少,甚至不移动
- 利用这种局部性可以提高吞吐量,减少队列长度
- 只要一个作业积极地使用文件系统,它就可以尽可能快地得到处理
- 如果由于工作量大而磁盘保持忙状态,就有可能出现饿死的情况
- 当一个作业已经往队列中送入一个 I/O 请求,并且错过了可以提供服务的位置时,该作业就有可能永远得不到服务,除非它之前的队列变为空
补充:单向扫描
- 移动臂总向一个方向扫面,归途中不提供服务
- 适用于不断有大量柱面均匀分布的请求的情形
- 要求磁头臂仅仅沿一个方向移动,并在途中满足所有为完成的请求,直到它到达这个方向上的最后一个磁道,或者在这个方向上没有其他请求为止,后一种改进有时候称为 LOOK 策略(又称为电梯调度算法)
- 接着反转服务方向,沿着相反方向扫描,同样按顺序完成所有请求
旋转调度 *
目的:使得旋转延迟的总时间最少
循环排序 *
通过优化 I/O 请求排序,在最少旋转圈数内完成位于同一柱面的访问请求
旋转位置测定硬件和多磁头同时读写技术有利于提高旋转调度的效率
考虑磁道上保存四个物理块的旋转型设备,旋转 1 周需时 20ms,假定收到以下四个 I/O 请求。请求次序记录号:读记录 4、读记录 3、读记录 2、读记录 1
多种循环排序:
- 方法 1:按照 I/O 请求次序读记录 4、3、2、1,平均用 1/2 周定位,再加上 1/4 周读出记录,总处理时间等于 1/2+1/4+3*3/4=3 周,即 60ms。
- 方法 2:如果次序为读记录 1、2、3、4,总处理时间等于 1/2+1/4+3*1/4=1.5 周,即 30ms。
- 方法 3:如果知道当前读位置是记录 3,则采用次序为读记录 4、1、2、3,总处理时间等于 4*1/4 = 1 周,即 20ms。
优化分布
- 通过信息在存储空间的排列方式来减少旋转延迟
- 交叉因子:如果沿着磁道按序对扇区编号,可能由于磁盘转速太快,造成处理当前扇区的数据时,下一个扇区已经跳过,需要再转一圈才能继续读数据。因此,对扇区编号时会间隔编号,例如交叉因子为 2:1 表示相邻编号之间会间隔 1 个扇区,3:1 表示会间隔 2 个扇区。
- 按柱面而非盘面进行数据读写:连续记录数据时,先记录在同一柱面的不同磁道上,然后再更换柱面,可以减少数据读写时的移臂操作
实例:考虑 10 个逻辑记录 A,B,……,J 被存于旋转型设备上,每道存放 10 个记录,安排如下:
- 按照优化前:处理 10 个记录的总时间:10ms(移动到记录 A 的平均时间)+ 2ms(读记录 A)+4ms(处理记录 A)+9*[16ms(访问下一记录)+2ms(读记录)+4ms(处理记录)] = 214ms
- 按照优化后:处理 10 个记录的总时间为:10ms(移动到记录 A 的平均时间)+10*[ 2ms(读记录)+ 4ms(处理记录)]=70ms
优化前 | 优化后 |
---|---|
提高磁盘 I/O 速度的办法 *
- 提前读:按照顺序访问时,可以读当前磁盘块时,提前把下一个磁盘块的数据也读入磁盘缓冲区。
- 延迟写:由于缓冲区的数据不久以后还会再次被进程访问,因此不立即将缓冲区中的数据写回盘,而是挂载空闲缓冲区队列队尾,直到移动到空闲缓冲区队首时在写回。
- 虚拟盘:用内存空间仿真磁盘,又叫 RAM 盘,相应的操作在内存中执行而不是硬盘中,比如:浏览器缓存等。
虚拟设备
虚拟设备:使用一类物理设备模拟另一类物理设备的技术,让独享型设备变为共享设备。
示例:
- 内存卡模拟磁盘
- 块设备模拟字符设备
- 输入输出重定向
一个经典的 SPOOLing 系统
- 在内核外运行的系统 I/O 软件,采用预输入、缓输出和井管理技术,是多道程序设计系统中处理独占型设备的一种方法,通过创建守护进程和特殊目录解决独占型设备的空占问题
- 为存放输入数据和输出数据,系统在磁盘上开辟输入井和输出井。“井”是用作缓冲的存储区域,采用井的技术能调节供求之间的矛盾,消除人工干预带来的损失。
- 不仅设备利用率提高,作业的运行时间也会缩短,每个作业都感觉各自拥有所需的独占设备
chatGPT 对 SPOOLing 的描述如下:
Spooling(Simultaneous Peripheral Operations On-line,同时操作外围设备)技术是一种计算机数据处理技术,它用于处理多个用户同时请求访问同一外围设备的情况。Spooling 技术的主要思想是,将外围设备的输入或输出数据缓存到磁盘或其他存储介质中,以便后续的处理和调度。
举个例子来说明,比如打印机是一个常见的外围设备。在没有 Spooling 技术的情况下,如果多个用户同时请求打印,打印机可能只能先响应其中一个用户的请求,而其他用户需要等待很长时间。这是因为打印机一次只能处理一份文件,而且每个打印任务可能需要花费较长的时间。
而采用 Spooling 技术后,用户的打印请求不是直接发送给打印机,而是先缓存到磁盘中。这样,所有的打印请求都可以在磁盘上排队等待打印,打印机只需要从磁盘中读取并打印每个任务即可。这种方式可以提高打印机的利用率,减少用户的等待时间。
在计算机系统中,Spooling 技术不仅用于打印机,还可以用于其它外围设备,比如磁带机、磁盘驱动器、网络设备等等。通过 Spooling 技术,系统可以更高效地利用外围设备,减少用户的等待时间,提高数据处理的效率。
SPOOLing 设备组成
- 预输入程序:
- 将数据从输入设备传送到磁盘输入井
- 作用:操作系统将一批作业从输入设备上预先输入到磁盘的输入缓冲区中暂时保存,这称为“预输入”
- 此后,由作业调度程序调度作业执行,作业使用数据时不必再启动输入设备,只要从磁盘的输入缓冲区中读入
- 缓输出程序:
- 将数据从磁盘输出井传送到输出设备
- 作用:作业执行中不必直接启动输出设备,只要将作业的输出数据暂时保存到磁盘的输出缓冲区
- 当作业执行完毕后,由操作系统组织信息成批输出
- 井管理程序:
- 控制作业和井之间的数据交换
- 放置在井中的文件被称为井文件,经文件空间管理简单,它被划分为等长的的物理块,每块用来存放一条或多条逻辑记录。
- 系统有一张作业表来登记进入系统的所有作业的 JCB,包括作业名、作业状态等信息。
- 预输入表用来登记作业的各个输入文件的情况。
- 缓输出表用来登记作业的各个输出文件的情况。
输入井的作业状态
- 输入状态:正在预输入
- 收容状态:预输入完成,等待执行
- 执行状态:作业选中执行,正在从输入井读取输入,向输出井写入数据
- 完成状态:作业已经撤离,输出结果等待缓输出。
- 通过预处理,结合井管理,可以实现为脱机状态,从联机(online)脱机(offline),成功耦合。
- 作业调度:决定有生命周期的进程的道数
SPOOLing 步骤
- 预输入:操作系统将作业需要的输入数据成批从输入设备上预先输入至磁盘的输入缓冲区中暂存:调度作业执行时,作业使用数据不必再启动输入设备,从磁盘的输入缓冲区读入即可
- 缓输出:作业不启动输出设备,只是将输出数据暂存到磁盘的输出缓冲区:作业执行完毕后,处理器空闲时,操作系统调用缓输出程序执行缓输出。
打印机 SPOOLing
打印机空占问题:如果用户进程通过打开打印机的设备文件来申请和使用打印机,往往会造成该进程打开设备文件后长达数小时不用,但其他进程又无法使用打印机
打印机守护进程和 SPOOLing 打印目录
- 守护进程是唯一有特权使用打印机设备的进程
- 打印文件前,用户进程先产生完整的待输出文件,并存放在打印目录下
- 打印机空闲时,启动守护进程,打印待输出文件
网络通信 SPOOLing 守护进程 *
- SPOOLing 技术不仅可用于打印机,还可用于其他场合。
- 例如,在网络上传输文件常使用网络守护进程,发送文件之前先将其放在特定的网络 SPOOL 目录下,而后由网络通信守护进程将其取出并发送出去。
- 这种文件传送方式的用途之一是因特网电子邮件系统
- 此网络将全世界数以千万台计的计算机连接在一起,通过通信网络进行通信。
- 当向某人发送电子邮件时,用户使用一个类似于 send 的程序,它接收所要发送的信件并将其送人固定的电子邮件 SPOOL 目录下等待以后发送,整个电子邮件系统在操作系统之外作为一种应用程序运行。
磁盘循环冗余阵列 *
RAID 0(无冗余)
- RAID 0 连续的数据条带(每个条带可规定为 1 个或多个扇区)以轮转方式写到全部磁盘上。
- 然后,采用并行交叉存取,减少 I/O 请求排队时间,适用于大数据量的 I/O 请求,但并无冗余校验功能,可靠性较差。
RAID 1(镜像)
- RAID 1 采用镜像盘双份所有数据来提高容错性,读请求拥有最小寻道时间,写请求可并行完成。缺点是容量下降一半,故成本很高
RAID 2(通过海明码冗余)
- RAID 2 采用数据字或字节交叉存放,并行存取获得高性能,使用海明校验码,适合大量顺序数据访问。由于使用多个冗余盘,成本较高
- 海明校验码
- 按照海明码编码方式我们首先对原数据生成新数据,然后之后校验数据将对应校验码做异或,如果全为 0 则为正确,否则则为错误位置。
RAID 3(交错位奇偶校验)
RAID 3 是 RAID 2 的简化版本,差别是它仅用一只冗余盘,采用奇偶校验技术。
RAID 4(块奇偶校验)
RAID 4 采用独立存取磁盘阵列,数据条带交叉存放,访问请求可并行地获得满足,适合有较高 I/O 请求速度的应用场合,使用一只冗余盘存放奇偶校验 90 码。
RAID 5(块分布奇偶校验)
RAID 5 与 RAID 4 的组织类似,但奇偶校验码循环分布在每个盘上使容错性更好。
RAID 6(双重冗余)
RAID 6 采用双重冗余技术, P 和 Q 是两种不同的数据校验算法,其中一种是 RAID 4 和 RAID 5 所使用是异或计算,另一种是独立数据校验算法,即使有两个数据磁盘发生错误,也可重新生成数据。
磁盘 Cache
- 磁盘高速缓存是主存中为磁盘扇区设置的一个缓冲区,包含磁盘中某些扇区的副本
- 利用局部性原理,可以减少平均存储器存取时间
替换策略:LRU
- 替换在高速缓存中未被访问的时间最长的块
- 逻辑上,高速缓存有一个关于块的栈组成,最近访问过的块在栈顶,当高速缓存中的一个块被访问到时,它从栈中当前的位置移到栈顶
- 当一个块从辅存中取入时,把位于栈顶的那一块移出,并把新到来的块压入栈顶
- 并不需要在主存中真正移动这些块,有一个栈指针与高速缓存相关联
替换策略:LFU(Least Frequently Used)
- 替换集合中被访问次数最少的块
- LFU 可以通过给每个块关联一个计数器来实现
- 当一个块被读入时,它的计数器被指定为 1;当每次访问到这一块时,它的计数器增 1
- 当需要替换时,选择计数器值最小的块
- 直觉上,LFU 比 LRU 更适合,因为 LFU 使用了关于每个块的更多的相关信息