操作系统系列笔记(八) - I/O系统

I/O系统

I/O特点

三种常见设备接口类型
字符设备: 以字节为单位顺序访问, 通常使用文件访问接口和语义, 例如键盘鼠标
块设备: 均匀的数据块访问, 原始I/O接口或文件系统接口, 内存映射文件访问, 例如磁盘驱动器, 光驱
网络设备: 格式化报文交换, 专用的网络报文收发接口, 通过网络接口支持多种网络协议, 例如以太网, 无线, 蓝牙
同步和异步I/O
阻塞I/O: wait, 读数据时, 进程将进入等待状态, 直到完成数据读出, 写数据时, 进程将进入等待状态, 直到设备完成数据写入处理
非阻塞I/O: don’t wait, 立即从读或写系统调返回, 返回值为成功传输字节数, 读或写的传输字节可能为零
异步I/O: tell me later, 读数据时, 使用指针标记好用户缓冲区, 立即返回, 稍后内核将填充缓冲区并通知用户, 写数据时, 使用指针标记好用户缓冲区, 立即返回, 稍后内核将处理数据并通知用户

I/O结构

CPU在主板上分成两段, 北桥和高速的内存显卡相连, 南桥和各种各样设备相连, 比如PCI总线, 磁盘, 网络
北桥高速设备, 南桥I/O设备
CPU和设备的连接: 设备上有设备控制器, 功能是提供CPU和I/O设备间的接口, 向CPU提供特殊指令和寄存器, I/O地址通过总线连到CPU上, 总线和实际设备之间有总线适配器,映射过来可能是内存地址, 也可能是I/O空间的端口
从设备到CPU的通道, 就是中断控制器, 设备产生中断在中断控制器进行汇总, 然后送给CPU, CPU就能对外部设备的事件做出相应
CPU和设备通信的三种方式: 轮询(不用中断控制器, CPU直接访问I/O端口, 或者访问设备对应的内存地址空间), 设备中断, DMA(Direct Memory Access)控制器

I/O指令和内存映射I/O:
I/O指令: 通过I/O端口号访问设备寄存器, 通过端口号区别访问的哪个设备, 特殊的CPU指令, OUT/IN两个指令, 不仅仅是数据的访问, 还对应相应的设备控制
内存映射I/O: 设备的寄存器/存储被映射到内存物理地址空间中, 通过内存load/store指令完成I/O操作, 通过MMU(Memory Management Unit)设置映射, 硬件跳线或程序在启动时设置地址

内核I/O子系统结构: 最底层各种各样设备, 每个设备之上有设备控制器, 再之上是驱动软件, 上是I/O子系统, 上是内核其他部分内容依赖I/O子系统完成数据读写
I/O请求生命周期
用户进程发起I/O请求 -> 内核I/O子系统 -> 向设备驱动发送I/O请求, 并等待结果 -> 设备驱动处理I/O请求转换成设备控制命令发送给硬件并等待中断相应 ->
硬件设备完成时, 产生中断 -> 中断处理例程接受中断, 保存结果并通知设备驱动 -> 通知驱动层, 确定I/O操作完成状态, 区分返回结果和哪个请求相对应 ->
结果给到I/O子系统当中 -> 送给用户进程

I/O数据传输

CPU与I/O设备的数据传输有两种方式
程序控制I/O(PIO, Programmed I/O): 通过CPU的In/Out或者load/store传输所有数据, 特点是硬件简单, 编程容易, 消耗的CPU时间和数据量成正比, 适用于简单的小型设备I/O
直接内存访问(DMA): 设备控制器可直接访问系统总线, 控制器直接与内存互相传输数据, 特点是设备传输数据不影响CPU, 开始和结束需要CPU参与设置, 适用于高吞吐量I/O

I/O设备通知操作系统的机制如下, 了解设备状态, I/O操作完成时间或遇到错误
CPU主动轮询: I/O设备在特定的状态寄存器中放置状态和错误信息, 操作系统定时检测状态寄存器, 优点是简单, 但I/O操作频繁或不可预测时, 开销大和延时长
设备中断: 处理不可预测事件效果好, 开销相对较高
一些设备结合了轮询和设备中断, 如高带宽网络设备, 第一个传入数据包到达前采用中断, 轮询后面的数据包直到硬件缓存为空

磁盘调度

磁盘结构分为: 磁头, 磁头组, 磁盘轴, 盘片, 读写头, 磁道, 扇区, 柱面
读取或写入时, 磁头必须被定位在期望的磁道, 并从所期望的柱面和扇区开始
寻道时间: 定位到期望的磁道所花费的时间
旋转延迟: 从零扇区开始到达目的地花费的时间
磁盘io传输时间: 等待设备可用, 等待通道可用, (寻道, 旋转延时, 数据传输)传输时间

磁盘调度算法, 通过优化磁盘访问请求顺序来提高磁盘访问性能, 寻道时间是磁盘访问最耗时的部分, 同时会有多个在同一磁盘上的I/O请求, 随机处理磁盘访问请求的性能表现很差
先进先出: 公平但性能不好, 很多进程的情况下, 接近随机调度的性能
最短服务时间优先(SSTF): 选择从磁臂当前位置需要移动最少的I/O请求, 总是选择最短寻道时间
扫描算法(SCAN): 磁臂在一个方向上移动, 访问所有未完成的请求, 直到磁臂到达该方向上最后的磁道
循环扫描算法(C-SCAN): 限制了仅在一个方向上扫描, 当最后一个磁道也被访问过了后, 磁臂返回到磁盘的另一端再次进行
N步扫描算法(N-STEP-SCAN): 将磁盘请求队列分成长度为N的子队列, 按FIFO依次处理所有子队列, 扫描算法处理每个队列
双队列扫描算法(FSCAN): N步扫描算法的简化, 只将磁盘请求队列分成两个子队列, 交替使用扫描算法处理一个队列, 新到达的请求放入另一个队列, 所有的新请求都将被推迟到下一次扫描时处理, 平均等待时间会减少

磁盘缓存

缓存是数据传输双方访问速度差异较大时, 引入的速度匹配中间层
放在内存里的磁盘数据的缓存, 为了避免对同一块磁盘扇区里的内容进行反复引用时候的多次磁盘访问
磁盘缓存的调度算法很类似虚拟存储调度算法, 磁盘的访问频率远低于虚拟存储中的内存访问频率, 所以通常磁盘缓存调度算法会比虚拟存储复杂
单缓存和双缓存, 单缓存一个缓存区, 读写互斥, 双缓存, 有两个缓存区, 写1读2, 写2读1
访问频率置换算法(Frequency-Based Replacement): 考虑磁盘访问的密集特征, 对密集引用不计数, 在短周期中使用LRU, 在长周期中使用LFU
具体实现: LRU栈被分为新区域, 中间区域, 旧区域三部分, 被访问就放入栈顶(LRU)也就是新区域, 新区域引用计数不变, 中间和旧区域会加一, 满了以后置换旧区域引用计数最大的块(LFU)

操作系统系列到此结束

打赏
  • 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!
  • © 2017-2023 王丹鹏
  • Powered by Hexo Theme Ayer
  • 冀ICP备15029707号

请我喝杯咖啡吧~

支付宝
微信