$ cat ~ / posts /jsjzcyl /jz7 12.4k Words ~ 44 Mins
cover.png
计组学习笔记6

#计组学习笔记6

exdoubled Lv5

I/O 系统概述

输入输出系统的任务是让主机和外部设备交换信息。

这里的主机通常指 CPU、主存和相关控制部件。

外设包括键盘、鼠标、显示器、打印机、磁盘、网卡、声卡、USB 设备等。

I/O 系统要解决的问题不是单纯的“传数据”。

它还要解决:

  • CPU、主存和外设之间怎样建立传输通路
  • 用户 I/O 请求怎样转换成设备命令
  • 外设怎样编址
  • CPU 怎样找到要访问的设备
  • 主机和外设速度不匹配时怎样缓冲
  • 外设完成任务或出错时怎样通知 CPU
  • I/O 硬件和操作系统怎样协同工作

所以 I/O 系统同时涉及硬件、指令系统、操作系统和设备驱动。

I/O 子系统可以看成计算机与外部世界之间的接口层。它不仅负责传送数据,还要把外部世界的物理信息转换成计算机能处理的二进制信息,并把计算机输出再转换成外设能表现的形式。

I/O 性能指标

I/O 系统常用两个性能指标:

指标含义关注场景
吞吐率单位时间内完成多少数据传输或多少次 I/O 操作文件服务器、多媒体、大数据
响应时间从发出请求到请求完成需要多久交互式系统、数据库事务

吞吐率也称 I/O 带宽。

响应时间也称等待延迟。

两者不总是一致。

I/O 性能长期落后于 CPU 性能,因此很多系统瓶颈并不在计算,而在数据进出。吞吐率更像系统或服务提供者关心的指标,响应时间更像单个用户关心的指标。

例如视频播放更关心持续吞吐率,银行取款更关心单次请求响应时间。

文件服务器和 Web 服务器通常两者都重要。

外部设备

外设分类

按交互对象划分:

类型含义例子
人机交互设备输入输出的信息人可以直接理解键盘、鼠标、显示器、打印机
机器可读设备信息主要供机器处理,人不能直接读磁盘、网卡、A/D、D/A、Modem

按功能划分:

类型功能例子
输入设备将外部信息送入主机键盘、鼠标、扫描仪
输出设备将主机信息输出到外部显示器、打印机、绘图仪
外存设备保存大量机器可读信息磁盘、光盘、磁带、SSD

按数据交换方式也可粗略分为:

  • 字符型设备
  • 块设备

字符型设备一次传送少量字符,常用中断或查询。

块设备一次传送一批数据,常用 DMA。

外设特点

外设和 CPU、主存相比有几个明显特点:

  • 种类多
  • 速度差异大
  • 控制方式不同
  • 数据格式不统一
  • 很多设备带机械动作或物理转换过程

例如键盘输入是人的按键动作,磁盘访问涉及机械寻道和旋转,网卡数据来自网络协议。

这些复杂差异不能直接暴露给 CPU。

因此主机通常不直接控制外设本体,而是通过 I/O 接口或设备控制器来控制。

外部设备通用模型

外部设备可以抽象为:

  • 控制逻辑
  • 缓冲器
  • 变换器
  • 与 I/O 接口连接的电缆或连接器

控制逻辑根据主机命令控制设备动作,并检测设备状态。

缓冲器暂存输入或输出数据,用来适配主机和设备速度差异。

变换器负责把设备侧物理信号转换成计算机内部二进制数据,或反向转换。

设备和 I/O 接口之间通常有三类信号:

  • 控制信号
  • 状态信号
  • 数据信号

所有设备虽然物理形式不同,但都可以抽象成命令、状态和数据三类信息的交换。

常用输入输出设备

键盘

键盘通常由按键矩阵和键盘控制逻辑组成。

按键矩阵通过行列扫描确定哪个键被按下。

扫描得到的是位置码或扫描码。

之后可以由键盘控制器或操作系统中的键盘中断服务程序转换成字符编码。

键盘控制器还会处理:

  • 按键抖动
  • 扫描码缓冲
  • 自动重复
  • 串行数据发送

键盘输入一般通过中断通知 CPU。

也就是键盘控制器接收到按键后,向 CPU 发出中断请求。

打印机

打印机是输出设备。

从工作原理看,可以分为:

  • 击打式打印机
  • 非击打式打印机

击打式打印机通过机械撞击色带或纸张形成字符。

非击打式打印机包括激光打印机、喷墨打印机等。

打印机通常速度很慢,因此需要数据缓冲和状态检测。

CPU 输出数据时,一般不是直接驱动打印机械动作,而是把字符或打印数据送到打印控制器的数据缓冲区。

打印机完成当前字符或当前行后,再通过状态位或中断通知主机继续传送。

显示器

显示器由显示设备和显示控制器组成。

早期 CRT 显示器通过电子束扫描荧光屏形成图像。

LCD 显示器利用液晶单元通电后改变排列状态来控制光线通过。

显示器常见工作模式:

模式显存内容特点
字符模式字符编码和属性字形由字符发生器给出
图形模式像素点阵信息每个像素可独立控制

图形模式下,显示存储器保存屏幕上每个像素的颜色或灰度信息。

显存容量和分辨率、颜色深度有关。

例如分辨率为 \(1920 \times 1080\),每个像素 32 位,则一帧需要: \[ 1920 \times 1080 \times 4B \approx 7.9MB \]

磁盘存储器

磁盘在第七章已经作为外存介绍过。

第八章更关注它作为 I/O 设备时怎样和主机传输数据。

磁盘读写以扇区为单位。

主机访问磁盘时,一般不是 CPU 逐字节搬运数据,而是通过磁盘控制器和 DMA 完成一批数据传送。

磁盘信息记录

磁盘表面由磁性介质组成。

写入时,磁头线圈通入不同方向的电流,使磁介质形成不同磁化状态,用来表示 0 或 1。

读出时,磁头感应到磁化单元产生的电压变化,根据电压极性和变化恢复二进制信息。

磁盘地址传统上可用三元组表示:

  • 柱面号
  • 磁头号
  • 扇区号

柱面号决定磁头移动到哪个半径。

磁头号决定选择哪个盘面。

扇区号决定等待哪个扇区转到磁头下方。

磁道和扇区

盘面上的同心圆称为磁道。

每个磁道分为若干扇区。

早期常见扇区大小为 512B。

现代磁盘逐渐采用 4096B 扇区,也就是 4K 扇区。

提高磁盘容量的方式主要有:

  • 增加磁道数,提高道密度
  • 增加每磁道扇区数,提高位密度
  • 采用可变扇区数,使外圈磁道保存更多扇区

早期磁盘每个磁道扇区数相同,外圈空间利用不充分。

现代磁盘通常让外圈磁道有更多扇区,提高整体容量。

平均存取时间

磁盘一次访问的响应时间通常包括: \[ T = T_{seek}+T_{rotation}+T_{transfer}+T_{controller}+T_{queue} \]

其中:

  • \(T_{seek}\):寻道时间
  • \(T_{rotation}\):旋转等待时间
  • \(T_{transfer}\):数据传输时间
  • \(T_{controller}\):控制器开销
  • \(T_{queue}\):排队等待时间

如果忽略控制器开销和排队时间,可以近似写成: \[ T \approx 平均寻道时间 + 平均旋转等待时间 + 数据传输时间 \]

平均旋转等待时间约为半圈时间。

如果磁盘转速为 \(r\) RPM,则每秒转数为: \[ RPS=\frac{r}{60} \]

半圈等待时间为: \[ T_{rotation} \approx \frac{1}{2RPS} \]

例如转速为 5400 RPM: \[ RPS=\frac{5400}{60}=90 \]

平均旋转等待时间约为: \[ \frac{1}{2 \times 90}s \approx 5.56ms \]

磁盘响应时间例子

假设:

  • 扇区大小 512B
  • 转速 5400 RPM
  • 平均寻道时间 12ms
  • 数据传输率 4MB/s
  • 控制器开销 1ms
  • 无排队时间

数据传输时间为: \[ \frac{0.5KB}{4MB/s} \approx 0.125ms \]

所以磁盘响应时间约为: \[ 12ms+5.56ms+0.125ms+1ms \approx 18.7ms \]

磁盘转速对响应时间影响很大。

当实际寻道时间因局部性而变小后,旋转等待时间会占更大比例。

磁盘读一个扇区

读一个磁盘扇区的大致过程:

  • CPU 初始化磁盘控制器
  • 写入读命令
  • 写入磁盘逻辑块号
  • 写入主存缓冲区起始地址
  • 启动磁盘驱动器
  • 磁盘控制器定位并读取扇区
  • 磁盘控制器按 DMA 方式把数据送入主存
  • DMA 结束后,磁盘控制器向 CPU 发出中断
  • CPU 执行后处理

注意:

CPU 只负责初始化和结束处理。

真正的数据搬运由磁盘控制器和 DMA 控制器完成。

RAID

RAID 是冗余磁盘阵列。

它把多个物理磁盘组织成一个逻辑磁盘。

RAID 的目的通常包括:

  • 增大容量
  • 提高传输率
  • 提高可靠性
  • 降低单个磁盘故障带来的数据丢失风险

RAID 通过条带化让多个磁盘并行工作。

通过冗余信息实现错误恢复。

RAID 0

RAID 0 只有条带化,没有冗余。

优点:

  • 容量利用率高
  • 并行读写性能好
  • 适合非关键的大容量高速数据

缺点:

  • 无容错能力
  • 任意一个磁盘损坏都可能导致数据不可用

RAID 1

RAID 1 是镜像。

一份数据写到两个磁盘中。

优点:

  • 可靠性高
  • 读操作可以选择较快的磁盘
  • 恢复简单

缺点:

  • 容量利用率只有约一半
  • 写操作需要更新两个副本

常用于可靠性要求高的系统数据。

RAID 2

RAID 2 使用海明校验码和多个校验盘。

它可以纠正一位错误、检测两位错误。

但校验盘数量和数据盘数量相关,冗余开销大。

实际系统中很少使用。

RAID 3

RAID 3 采用小条带交叉分布,并使用单独奇偶校验盘。

适合大块连续数据传输。

缺点是多个磁盘通常需要同步工作,小 I/O 响应时间不好。

RAID 4

RAID 4 采用块级条带化,并使用专用校验盘。

不同磁盘可以独立处理读请求。

但写操作需要更新校验盘。

当写请求频繁时,校验盘容易成为瓶颈。

RAID 5

RAID 5 和 RAID 4 类似,但奇偶校验块分布在各个磁盘上。

这样避免专用校验盘成为瓶颈。

RAID 5 成本、性能和可靠性较均衡,服务器中常见。

RAID 6

RAID 6 在 RAID 5 基础上增加更多冗余校验信息。

它可以容忍更多磁盘故障。

代价是写入开销和校验开销更大。

RAID 和备份

RAID 不是备份。

RAID 主要提高可用性。

如果用户误删文件、病毒加密文件、文件系统损坏,RAID 可能会把错误同步到所有磁盘。

所以重要数据仍然需要独立备份。

总线概述

总线是在多个部件之间传送信息的一组公共信号线和相关控制规则。

它提供部件之间的连接通路。

总线上传输的信息主要包括:

  • 数据
  • 地址
  • 控制信号
  • 状态信号
  • 定时信号

按层次可以分为:

类型位置例子
芯片内总线芯片内部部件之间CPU 内部寄存器、ALU、控制器之间
系统总线CPU、主存、I/O 控制器之间早期处理器总线、系统总线
通信总线主机和外设或系统之间USB、SATA、PCIe、以太网

现代系统中的“总线”不一定是传统共享并行总线。

很多高速互连已经变成点对点、串行、包交换形式。

总线组成

系统总线通常包括:

信号线作用
数据线传送数据、指令、中断类型号等
地址线指出要访问的主存单元或 I/O 端口
控制线指出读写、仲裁、响应、中断等控制信息

有些总线没有单独地址线。

地址和数据可以复用同一组信号线。

这称为地址/数据复用。

地址/数据复用可以减少引脚数,但一个事务中需要分阶段传输地址和数据。

总线事务

总线事务是一次完整的总线操作。

常见事务包括:

  • 存储器读
  • 存储器写
  • I/O 读
  • I/O 写
  • 中断响应
  • DMA 总线请求和响应

一次存储器读事务大致包含:

  • 主设备获得总线控制权
  • 在地址线上给出地址
  • 在控制线上给出读命令
  • 从设备响应
  • 数据出现在数据线上
  • 主设备接收数据

总线协议规定每一步何时发生,以及各信号之间的时序关系。

总线裁决

传统共享总线一次只能由一个主设备控制。

当多个设备都要使用总线时,需要总线裁决。

可能请求总线的主设备包括:

  • CPU
  • DMA 控制器
  • I/O 控制器

总线裁决决定谁获得总线使用权。

早期共享总线需要裁决。

现代点对点互连通常不再以传统方式裁决。

总线定时

总线定时定义事务中的每个动作何时开始、何时结束。

按定时方式可分为:

  • 同步总线
  • 异步总线

同步总线用公共时钟控制数据传送。

优点是控制简单、速度较快。

缺点是总线不能太长,各信号到达时间差会影响高速传输。

异步总线不用统一时钟,而用握手信号协调。

优点是能适配不同速度设备。

缺点是控制复杂,单次事务开销较大。

并行和串行

并行传输一次在多根线上同时传送多位数据。

串行传输一次在一根或一对线上按位传送。

早期总线常用并行方式。

现代高速互连越来越多采用串行方式。

原因是高速并行总线中,不同数据线之间的传播延迟差会造成时序困难。

串行链路虽然每次传一位,但可以使用更高频率和多通道组合获得更高总带宽。

PCI-Express 就是典型高速串行点对点互连。

非突发传送和突发传送

非突发传送中,每次传送都要给出地址。

一个地址对应一次数据传送。

突发传送中,先传送首地址,后面连续传送多个数据。

后续地址默认按规则自动递增。

突发传送适合 cache 块填充、内存块拷贝、磁盘 DMA 等连续数据访问。

总线性能指标

总线宽度

总线宽度通常指数据线条数。

它决定一次并行传输的数据位数。

例如 64 位数据总线一次可传送 8 字节。

总线工作频率

早期总线通常一个时钟周期传送一次数据。

此时工作频率等于时钟频率。

有些总线一个时钟周期传送 2 次或 4 次数据。

此时有效传输率是时钟频率的 2 倍或 4 倍。

总线带宽

总线带宽表示总线最大数据传输率。

对于同步总线: \[ B=\frac{W \times F}{N} \]

其中:

  • \(W\) 是总线宽度,通常用字节表示
  • \(F\) 是总线时钟频率
  • \(N\) 是完成一次数据传送需要的时钟周期数

也可以理解为: \[ 带宽 = 每次传送字节数 \times 每秒传送次数 \]

例如总线宽度 64 位,也就是 8B,有效传输率为 1333MT/s,则带宽为: \[ 8B \times 1333M/s \approx 10.7GB/s \]

总线寻址能力

地址线根数决定总线能直接寻址的空间大小。

如果有 \(n\) 根地址线,按字节编址,则最大寻址空间为: \[ 2^nB \]

如果地址/数据复用,总线的物理引脚数不一定直接等于地址位数。

基于总线的互连结构

单总线结构

单总线结构把 CPU、主存和 I/O 控制器都连接到同一条总线上。

优点:

  • 结构简单
  • 成本低
  • 扩展方便

缺点:

  • 总线成为瓶颈
  • CPU 访问主存和 I/O 访问主存会冲突
  • 高速设备和低速设备混在一起,不利于优化

多总线结构

多总线结构把系统划分为多个层次。

常见总线包括:

  • 处理器总线
  • 存储器总线
  • 高速 I/O 总线
  • 低速扩展 I/O 总线

不同总线之间通过桥接器、芯片组或控制器连接。

这种结构可以让高速通路保持短而快,同时把低速外设隔离在较低层次。

处理器总线

处理器总线连接 CPU 和芯片组或其他高速部件。

早期 Intel 处理器使用前端总线 FSB。

FSB 从 Pentium Pro 开始采用 quad pumped 技术,每个总线时钟周期传送 4 次数据。

例如实际时钟频率 333MHz,四倍传输后有效传输率约为 1333MT/s。

如果总线宽度为 64 位,则带宽约为: \[ 1333M/s \times 8B \approx 10.7GB/s \]

后来 Core i7 开始,内存控制器集成到 CPU 内部。

CPU 通过存储器总线直接连接内存条。

CPU 与 I/O Hub、CPU 与 CPU 之间则使用 QPI 等高速点对点互连。

QPI

QPI 是快速通道互连。

它是基于包传输的高速串行点对点连接。

QPI 使用发送和接收两个方向的链路。

如果 QPI 速度为 6.4GT/s,每次传输有效数据 2B,双向同时传输,则总带宽可写为: \[ 6.4G \times 2B \times 2 = 25.6GB/s \]

这类高速互连的单位常用 GT/s。

GT/s 表示每秒传输多少十亿次,不等同于时钟频率。

存储器总线

存储器总线连接 CPU 内存控制器和内存条。

DDR 内存一个时钟周期传送两次数据。

若内存总线宽度为 64 位,数据传输率为 1066MT/s,则单通道带宽为: \[ 8B \times 1066M/s \approx 8.5GB/s \]

如果三通道并行,则总带宽约为: \[ 3 \times 8.5GB/s = 25.5GB/s \]

课件中 Core i7 三通道 DDR3 例子就是这种计算方式。

I/O 总线

I/O 总线为系统中各种 I/O 设备提供输入输出通道。

常见 I/O 总线或接口包括:

  • ISA
  • PCI
  • PCI-Express
  • SATA
  • USB

PCI-Express 是现代主流高速 I/O 互连。

它采用串行点对点链路。

PCIe 由多个 lane 组成。

例如 PCIe x16 表示 16 条通路。

PCIe 1.0 每条通路每方向 2.5Gb/s,采用 8b/10b 编码后有效带宽约为: \[ 2.5Gb/s \times \frac{8}{10} = 2Gb/s = 250MB/s \]

双向合计每 lane 约 500MB/s。

所以 PCIe 1.0 x16 双向合计约为: \[ 0.5GB/s \times 16 = 8GB/s \]

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 通过访问这些寄存器来控制设备。

这些 CPU 能访问的寄存器称为 I/O 端口。

主机控制外设时,至少要能发送命令、读取状态、交换数据。状态信息不仅表示设备是否就绪,还要反映运行过程中是否出现错误。接口寄存器的设计,本质上就是为这三类信息提供可访问的位置。

I/O 端口

I/O 端口就是 I/O 接口中 CPU 可以访问的寄存器。

常见端口包括:

端口作用
数据端口读写设备数据
状态端口读取设备状态
控制端口写入控制命令

对外设的访问,本质上就是对这些端口发命令、读状态、读写数据。

一个 I/O 控制器可能占用多个端口地址。

例如打印机接口可能有:

  • 数据端口
  • 状态端口
  • 控制端口

CPU 必须能通过地址区分这些端口。

这就是 I/O 端口编址问题。

I/O 端口编址

I/O 端口编址有两种基本方式:

  • 独立编址
  • 统一编址

独立编址

独立编址把 I/O 端口和主存分开编号。

I/O 地址空间独立于主存地址空间。

访问 I/O 端口需要专门的 I/O 指令。

典型例子是 x86 的 INOUT 指令。

特点:

  • I/O 空间和主存空间分离
  • 指令系统需要专门 I/O 指令
  • 总线控制信号可区分 I/O 读写和存储器读写
  • I/O 地址线数量可以少于主存地址线

例如奔腾机采用独立编址方式,I/O 地址空间由 \(2^{16}\) 个 8 位端口组成。

两个连续 8 位端口可作为 16 位端口。

四个连续 8 位端口可作为 32 位端口。

统一编址

统一编址也称存储器映射 I/O。

它从主存地址空间中划出一部分地址给 I/O 端口使用。

CPU 用普通访存指令访问 I/O 端口。

特点:

  • 不需要专门 I/O 指令
  • 可使用普通 load/store 指令
  • 可使用普通寻址方式
  • 保护机制可和虚拟存储器结合
  • 会占用部分主存地址空间

MIPS、RISC-V 等 RISC 架构通常采用统一编址。

统一编址方式下,访问 I/O 端口不能被 cache 随意缓存。

因为设备寄存器的值可能随设备状态变化。

如果把 I/O 地址缓存到 cache,CPU 可能读到过时状态,或者写命令没有真正送到设备。

因此 I/O 空间通常映射到不可缓存区域。

两种编址方式比较

项目独立编址统一编址
地址空间I/O 和主存分离I/O 占用主存地址空间
指令需要专门 I/O 指令用普通访存指令
控制信号I/O 读写和存储器读写分开按地址范围区分
编程灵活性较低较高
典型架构x86MIPS、RISC-V

无论采用独立编址还是统一编址,CPU 都必须通过正确地址找到对应设备端口。如果端口号或映射地址配置错误,访问到的可能就是另一个设备。现代系统通常由固件和操作系统自动完成这些配置,减少人工出错。

I/O 数据传送控制方式

外设与主机之间的数据传送主要有三种方式:

  • 程序直接控制方式
  • 中断控制方式
  • DMA 方式

三者的主要区别是 CPU 参与程度不同。

方式数据传送由谁完成CPU 占用适合设备
程序查询CPU 执行程序搬运最高简单慢速设备
中断 I/OCPU 执行中断服务程序搬运中等低速或中速设备
DMADMA 控制器搬运最低磁盘等高速块设备

程序直接控制 I/O

程序直接控制方式由 CPU 执行程序来控制数据传送。

它又可以分为:

  • 无条件传送
  • 条件传送

无条件传送

无条件传送也称同步传送。

CPU 按固定时间访问 I/O 端口,不查询设备状态。

它适用于非常简单、时序确定的设备。

接口硬件简单,只需要数据锁存器或三态缓冲器。

缺点是设备必须和程序时序严格配合。

如果设备状态不确定,就可能读错或丢数据。

条件传送

条件传送也称查询方式或 polling。

CPU 不断读取状态寄存器,判断设备是否就绪。

如果设备未就绪,继续查询。

如果设备就绪,就执行数据传送并发出下一步控制命令。

典型过程:

  • 读状态端口
  • 判断就绪位
  • 未就绪则继续读状态
  • 就绪则访问数据端口
  • 发出启动或确认命令

程序查询方式特点

优点:

  • 硬件简单
  • 程序控制直接
  • 接口成本低

缺点:

  • CPU 和外设串行工作
  • CPU 大量时间浪费在等待上
  • 不适合高速设备
  • 不适合大量设备并发

课件里强调:查询期间 CPU 并没有停止。

它只是一直执行类似“读状态、测试、条件跳转”的指令。

因此 CPU 时间被 I/O 等待消耗。

程序查询方式的浪费不在于 CPU 停机,而在于 CPU 忙着执行无效等待循环。外设真正工作时,CPU 大量时间只是反复查看状态位,不能把这段时间让给其他有用计算。

中断控制 I/O

中断控制 I/O 的基本思想是:

CPU 启动外设工作后,继续执行其他程序。

外设准备好或完成任务时,向 CPU 发中断请求。

CPU 响应中断后,转入中断服务程序完成数据传送或后续控制。

这样 CPU 和外设可以在一定程度上并行。

中断 I/O 基本过程

以输出设备为例:

  • CPU 启动外设
  • CPU 执行其他程序
  • 外设完成当前操作
  • 外设向 CPU 发中断请求
  • CPU 在合适时刻响应中断
  • CPU 保存断点和状态
  • CPU 转入中断服务程序
  • 中断服务程序传送数据或启动下一次 I/O
  • 中断返回,继续原程序

外设接到启动命令后,可以独立完成机械动作或内部处理。CPU 不必一直等待,而是继续运行其他程序。等外设准备好后,再通过中断请求让 CPU 短暂转入服务程序。

中断 I/O 比查询方式减少了 CPU 主动等待。

但每次中断仍然需要保存现场、转入内核、执行中断服务程序。

所以它不适合每个字节都高速到来的设备。

中断响应条件

CPU 响应中断通常需要满足三个条件:

  • CPU 处于开中断状态
  • 当前指令执行完
  • 至少有一个未被屏蔽的中断请求

外部中断一般在一条指令执行结束后响应。

内部异常可能发生在指令执行过程中,不能简单等到指令结束后再处理。

这是中断和异常的重要区别。

中断响应过程

中断响应由硬件完成。

典型中断响应过程包括:

  • 关中断
  • 保护断点和程序状态
  • 识别中断源
  • 获得中断服务程序入口地址
  • 将入口地址送 PC
  • 将初始程序状态送 PSWR

保护断点和程序状态是为了中断返回后能继续执行原程序。

断点可以保存在栈中,也可以保存在专门寄存器中。

程序状态字 PSW 保存条件码、中断允许位、处理器模式等状态。

中断源识别

识别中断源有两类方式:

  • 软件查询
  • 硬件判优

软件查询方式中,CPU 转到统一中断入口,由软件按优先级查询状态寄存器,确定中断源。

MIPS 异常入口类似这种思想,通过 Cause 寄存器记录异常原因。

硬件判优方式中,中断控制器用硬件排队和编码,直接给出中断类型号。

CPU 根据中断类型号查中断向量表,得到中断服务程序入口。

向量中断响应速度更快。

中断向量表

中断向量表保存各类中断服务程序入口地址。

8086/8088 中断向量表位于 0000H03FFH

共有 256 个中断向量。

每个向量 4 字节,保存 CS:IP

向量地址为: \[ 向量地址 = 中断类型号 \times 4 \]

例如:

  • 类型号 0 的向量地址为 0
  • 类型号 2 的向量地址为 8

中断控制器

中断控制器负责集中管理多个外设中断请求。

典型功能:

  • 中断请求锁存
  • 中断屏蔽
  • 优先级排队
  • 中断类型号形成
  • 向 CPU 发出中断请求
  • 接收 CPU 的中断响应信号

Intel 8259A 是典型可编程中断控制器。

它支持 8 级中断。

多片级联可扩展更多中断源。

中断控制器中通常有:

  • 中断请求寄存器
  • 中断屏蔽寄存器
  • 优先级判优电路
  • 中断类型号形成线路

中断类型号通过数据线送给 CPU。

中断处理过程

中断响应结束后,CPU 开始执行中断服务程序。

中断处理由软件完成。

典型中断服务程序可分为:

阶段主要工作
先行段保存现场和旧屏蔽字,查明原因,设置新屏蔽字,开中断
本体段执行具体 I/O 或异常处理工作
结束段关中断,恢复现场和旧屏蔽字,清中断请求,开中断,中断返回

如果系统不支持多重中断,中断服务程序执行期间一般保持关中断。

如果支持多重中断,中断服务程序在准备阶段完成必要保护后可以重新开中断。

中断的开销不只是服务程序本身,还包括从当前程序切换到中断服务程序、再切换回来的现场保护和恢复。寄存器、程序状态和断点等信息通常要保存到栈或专门位置。中断服务程序越短,CPU 被 I/O 打断的代价就越低。

多重中断

多重中断也称中断嵌套。

它指在执行某个中断服务程序时,又发生了优先级更高的中断请求。

CPU 暂停当前中断服务程序,转去处理新的高优先级中断。

新中断处理完成后,再回到原中断服务程序继续执行。

中断系统中有两种优先级:

优先级含义决定方式
中断响应优先级多个中断同时请求时先响应谁查询顺序或硬件判优电路
中断处理优先级中断服务程序执行期间允许谁打断它中断屏蔽字

响应优先级是“先选谁进入”。

处理优先级是“正在处理时允许谁插队”。

这两个优先级可以不同。

查询方式和中断方式比较

设某设备输出一个数据时:

  • CPU 把数据送到接口缓冲器需要 \(1\mu s\)
  • 接口把缓冲器数据送到设备需要 \(1ms\)
  • 一条指令执行时间为 \(1\mu s\)

如果用程序查询方式,CPU 一直等待设备完成,主机占用率接近 100%。

如果用中断方式,CPU 只在中断响应和中断服务程序期间参与,外设工作期间可以执行其他程序。

中断方式通常主机占用率低很多。

但中断服务程序比查询程序长,因为有保存现场、设置屏蔽字、开关中断、中断返回等额外开销。

DMA 方式

DMA 是 Direct Memory Access,直接存储器存取。

它让高速外设和主存之间直接交换数据。

数据传送由 DMA 控制器完成,不需要 CPU 执行指令逐字搬运。

为什么需要 DMA

程序查询方式效率低。

中断方式虽然减少等待,但每传送一个数据都要产生中断,开销仍然大。

对于磁盘、网卡这类高速块设备,如果每 16B 或每个字都中断一次,CPU 开销会很高。

DMA 的目标是:

  • CPU 只负责初始化 DMA 控制器
  • 数据块传送过程由 DMA 控制器完成
  • 传送结束后再中断 CPU 做后处理

DMA 基本思想

DMA 方式下,外设准备好数据后,向 DMA 控制器发 DMA 请求。

DMA 控制器再向 CPU 发总线请求。

CPU 完成当前总线周期后让出总线。

DMA 控制器获得总线控制权后,直接在外设和主存之间传送数据。

DMA 方式请求的是总线控制权。

中断方式请求的是 CPU 执行中断服务程序。

这是两者的核心区别。

DMA 的“直接通路”是逻辑上的,并不是外设和主存之间随便拉一条独立物理线。DMA 控制器需要接管相关总线事务,只有获得总线使用权后,才能在外设和主存之间搬运数据。

DMA 适用场景

DMA 适合:

  • 高速设备
  • 成批数据交换
  • 数据之间间隔短
  • 一旦启动就连续读写

典型设备:

  • 磁盘
  • SSD
  • 网卡
  • 声卡
  • 高速采集卡

DMA 和中断结合

DMA 并不完全替代中断。

实际 I/O 过程中,DMA 常和中断配合:

  • 磁盘寻道完成,用中断通知 CPU
  • 磁盘旋转定位完成,用中断通知 CPU
  • 连续数据传送阶段,用 DMA
  • DMA 结束后,用中断通知 CPU

也就是说:

定位、启动、结束处理仍可能需要中断。

大批数据搬运交给 DMA。

DMA 控制器

DMA 控制器是能控制总线进行直接主存访问的接口硬件。

它通常包含:

  • 主存地址寄存器
  • 字计数器
  • 设备地址寄存器
  • 控制寄存器
  • 数据缓冲器
  • 总线请求和响应逻辑
  • 读写控制逻辑

DMA 控制器功能

DMA 控制器需要完成:

  • 接收外设 DMA 请求
  • 向 CPU 发总线请求
  • 接管总线控制权
  • 给出主存地址
  • 自动修改主存地址
  • 判断传送方向
  • 给出读写控制信号
  • 记录剩余传送数据个数
  • 传送结束后发 DMA 结束中断

DMA 初始化

DMA 传送前,CPU 需要初始化 DMA 控制器。

主要设置:

  • 主存缓冲区首地址
  • 传送字数或字节数
  • 传送方向
  • 设备地址
  • 控制命令

初始化完成后,CPU 启动外设,然后可以执行其他程序。

DMA 开始前仍需要 CPU 参与,但 CPU 的工作主要是告诉控制器从哪里传、传多少、按什么方向传。参数设置完成后,大块数据传送由硬件自动完成,因此适合磁盘、网卡等成批传输设备。

DMA 数据传送

DMA 传送过程由硬件完成:

  • 外设准备好数据或准备好接收数据
  • 外设向 DMA 控制器发 DMA 请求
  • DMA 控制器向 CPU 请求总线
  • CPU 响应并让出总线
  • DMA 控制器给出主存地址
  • DMA 控制器发读写命令
  • 数据在外设和主存之间传送
  • 主存地址自动增量
  • 字计数器减 1
  • 计数器为 0 时结束

DMA 结束处理

当字计数器为 0,DMA 控制器发出 DMA 结束中断请求。

CPU 响应后执行中断服务程序。

结束处理可能包括:

  • 检查传送是否成功
  • 进行校验
  • 更新 I/O 请求状态
  • 唤醒等待该 I/O 的进程
  • 释放或切换缓冲区

DMA 三种控制方式

DMA 控制器和 CPU 都可能访问主存。

因此两者会争用主存和总线。

DMA 常见控制方式有三种:

  • CPU 停止法
  • 周期挪用法
  • 交替分时访问法

CPU 停止法

CPU 停止法也称成组传送方式。

DMA 传送时,CPU 脱离总线,停止访问主存。

直到 DMA 传送完整块数据。

优点:

  • 控制简单
  • 适合传输率很高的设备
  • 成块传送效率高

缺点:

  • CPU 工作受影响
  • DMA 传送期间 CPU 基本不能访问主存
  • 主存周期可能不能充分利用

周期挪用法

周期挪用法也称周期窃取法。

DMA 每次只挪用一个主存周期。

传送一个数据后立即释放总线。

外设准备下一个数据时,CPU 可以继续访问主存。

优点:

  • 兼顾 DMA 响应和 CPU 执行
  • 主存利用率较好
  • 适合 I/O 设备读写周期大于主存周期的情况

缺点:

  • 每次 DMA 都要申请和释放总线
  • 控制开销较大
  • CPU 访存可能被延迟

当 CPU 和 DMA 同时要访问主存时,通常 DMA 优先。

因为高速外设如果不及时传送,可能丢失数据。

交替分时访问法

交替分时访问法把每个存储周期划分为两个时间片。

一个给 CPU。

一个给 DMA 控制器。

这样 CPU 和 DMA 在固定时隙中交替访问主存。

优点是冲突少、时序规则。

缺点是需要主存能支持这种分时访问节奏。

DMA 和中断的区别

项目中断方式DMA 方式
请求对象请求 CPU 执行服务程序请求总线控制权
数据传送者CPU 执行指令传送DMA 控制器硬件传送
是否中止程序需要中止当前程序数据传送期间通常不需要
响应时点指令周期结束后总线周期结束后
适合设备低速或中速设备高速块设备
异常处理能力可处理设备异常本身只负责数据传送

DMA 传送结束仍然要通过中断通知 CPU。

所以 DMA 和中断不是互斥关系,而是分工关系。

CPU 开销例子

假设:

  • CPU 主频 500MHz
  • 磁盘传输率 4MB/s
  • 硬盘控制器数据缓存器 16B
  • 中断方式每次传送开销 500 个时钟周期

如果用中断方式,每秒中断次数约为: \[ \frac{4MB/s}{16B}=250K/s \]

每秒用于中断的时钟周期: \[ 250K \times 500=125 \times 10^6 \]

占 CPU 总周期比例: \[ \frac{125 \times 10^6}{500 \times 10^6}=25\% \]

如果磁盘只用 5% 时间传输,则平均 CPU 开销为: \[ 25\% \times 5\%=1.25\% \]

若采用 DMA,每次传送 8000B,初始化 1000 周期,结束中断 500 周期。

一次 DMA 传送时间: \[ \frac{8000B}{4MB/s}\approx 2ms \]

每秒约 500 次 DMA。

每秒 CPU 开销: \[ 500 \times (1000+500)=750000 \]

占 CPU 总周期比例: \[ \frac{750000}{500 \times 10^6}=0.15\% \]

这说明高速块设备适合 DMA。

DMA 与存储系统

DMA 控制器直接访问主存,可能绕过 CPU 的 MMU 和 cache。

这会带来两个问题:

  • 地址转换问题
  • cache 一致性问题

地址转换问题

用户程序看到的是虚拟地址。

DMA 控制器访问主存需要物理地址。

如果操作系统把用户缓冲区地址直接给 DMA 控制器,可能无法正确访问。

常见处理方式:

  • 操作系统把用户缓冲区映射到物理页
  • 使用内核缓冲区
  • 使用 IOMMU 为设备提供地址转换
  • 锁定 DMA 传送期间涉及的页面,防止被换出

cache 一致性问题

DMA 不经过 CPU cache 时,cache 和主存可能不一致。

例如从磁盘读入数据时,DMA 把新数据写入主存。

如果 CPU cache 中仍有该主存块的旧副本,CPU 之后读取会得到旧值。

又如向磁盘写出数据时,如果 CPU 修改的数据还在写回 cache 中,没有写回主存,DMA 从主存读到的就是旧值。

解决方式包括:

  • 让 I/O 活动通过 cache
  • 操作系统在 DMA 前后执行 cache 刷新或失效
  • 硬件维护 I/O 一致性
  • 将 DMA 缓冲区映射为不可缓存区域

I/O 一致性是 cache 一致性在设备访问场景下的表现。

I/O 软件层次

I/O 系统不仅有硬件,也有大量操作系统软件。

所有高级语言运行时都提供 I/O 函数。

例如 C 语言中的 printf()scanf()fread()

但最终都要通过系统调用进入操作系统内核。

用户程序不能直接执行 I/O 指令。

因为 I/O 指令、开中断、关中断等通常是特权指令。

操作系统在 I/O 中的作用

OS 负责:

  • 管理共享 I/O 设备
  • 检查访问权限
  • 提供设备驱动程序
  • 屏蔽设备控制细节
  • 处理中断
  • 调度 I/O 请求
  • 管理缓冲区
  • 向用户程序提供统一接口

I/O 系统有共享性、复杂性和异步性。

这决定了大部分 I/O 软件必须在内核态完成。

I/O 软件四个层次

从高到低:

层次位置作用
用户层 I/O 软件用户态标准库、运行时、系统调用封装
与设备无关的 I/O 软件内核态统一接口、缓冲、错误报告、文件抽象
设备驱动程序内核态控制具体设备和 I/O 接口
中断服务程序内核态响应设备中断,完成底层处理

层次越低,越接近设备。

层次越高,越接近用户程序。

系统调用

用户态进入内核态通常通过异常机制,也就是系统调用。

例如 Linux IA-32 中曾使用 int $0x80 触发系统调用。

调用 printf() 的大致路径:

  • 用户程序调用 printf()
  • C 标准库处理格式化输出
  • 最终调用 write() 系统调用封装函数
  • 执行陷阱指令进入内核
  • 系统调用处理程序根据系统调用号找到 sys_write
  • sys_write 调用与设备无关 I/O 层和具体驱动
  • 驱动访问 I/O 端口或启动 DMA
  • 设备完成后可能触发中断

系统调用号通常放在约定寄存器中。

内核根据系统调用号跳转到对应服务例程。

用户态看到的 I/O 往往只是一个简单函数调用,但底层会经过系统调用进入内核。printf() 本身不是系统调用,它最终需要调用内核提供的写操作。一次读写请求在操作系统内部可能穿过很多层软件,最后才到达设备驱动和硬件接口。

与设备无关的 I/O 软件

与设备无关的 I/O 软件提供统一抽象。

主要工作:

  • 设备驱动程序统一接口
  • 缓冲区处理
  • 错误报告
  • 打开和关闭文件
  • 逻辑块大小处理
  • 设备名和文件名映射

例如 Unix/Linux 中设备也以文件形式出现。

用户访问设备文件时,内核根据设备号找到对应驱动。

设备驱动程序

设备驱动程序与具体设备相关。

它知道设备控制器有哪些端口、各状态位含义、命令格式、传输方式和中断处理方式。

不同 I/O 控制方式下,驱动行为不同:

  • 查询方式:驱动一直轮询状态,直到 I/O 完成
  • 中断方式:驱动启动第一次 I/O 后阻塞进程,之后由中断服务程序继续
  • DMA 方式:驱动初始化 DMA 控制器,启动 DMA 后阻塞进程,DMA 完成中断后唤醒

驱动程序是操作系统屏蔽设备差异的关键。

中断服务程序

中断控制和 DMA 控制都需要中断服务程序。

中断 I/O 中,中断服务程序通常负责:

  • 读写数据缓冲寄存器
  • 启动下一次设备操作
  • 更新状态
  • 清除中断请求

DMA 中,中断服务程序通常负责:

  • 确认 DMA 完成
  • 校验数据
  • 更新请求状态
  • 唤醒等待进程
  • 释放资源

中断服务程序应尽量短。

因为它运行在内核态,并且可能影响其他中断响应。

三种 I/O 方式的统一理解

CPU 参与程度

阶段查询方式中断方式DMA 方式
启动设备CPUCPUCPU
等待设备CPU 轮询CPU 可执行其他程序CPU 可执行其他程序
数据搬运CPUCPUDMA 控制器
完成通知CPU 查询状态设备中断DMA 结束中断

查询方式中,CPU 等。

中断方式中,CPU 不等,但 CPU 搬数据。

DMA 方式中,CPU 不等,也不搬大块数据。

选择原则

场景更适合方式
简单、低速、控制固定无条件或查询
低速、事件不频繁中断
高速、成块、连续数据DMA
设备状态变化需要及时处理中断
大批量数据进入主存DMA

典型题型整理

总线带宽

总线带宽题先找:

  • 总线宽度
  • 每秒传送次数
  • 每次传送需要几个周期
  • 是否双向同时传输
  • 是否有编码开销

基本公式: \[ B=\frac{W \times F}{N} \]

如果题目给的是 MT/s 或 GT/s,通常已经是有效传输次数,不一定等于时钟频率。

磁盘响应时间

磁盘响应时间题按:

  • 平均寻道时间
  • 平均旋转等待时间
  • 传输时间
  • 控制器开销
  • 排队时间

平均旋转等待约为半圈: \[ T_{rotation}=\frac{1}{2 \times RPM/60} \]

传输时间: \[ T_{transfer}=\frac{传输数据量}{数据传输率} \]

I/O 编址

判断独立编址还是统一编址:

  • IN / OUT 等专门 I/O 指令,通常是独立编址
  • 用普通 load/store 访问设备寄存器,通常是统一编址

统一编址要注意不可缓存区域。

因为设备寄存器不是普通内存。

中断过程

中断题要区分:

  • 中断响应由硬件完成
  • 中断处理由软件完成
  • 响应优先级决定同时请求时先响应谁
  • 处理优先级由屏蔽字决定能否嵌套

中断响应基本操作:

  • 关中断
  • 保存断点和 PSW
  • 识别中断源
  • 转中断服务程序

DMA 过程

DMA 题要区分三个阶段:

  • 初始化:CPU 软件完成
  • 数据传送:DMA 硬件完成
  • 结束处理:CPU 中断服务程序完成

DMA 三种主存使用方式:

  • CPU 停止法:块传送,CPU 停
  • 周期挪用法:单次挪用,常用
  • 交替分时法:固定时间片

小结

第八章的核心是主机如何与外设互连和交换数据。

要点如下:

  • I/O 性能主要看吞吐率和响应时间
  • 外设通过 I/O 接口与主机连接
  • I/O 接口提供数据缓冲、状态检测、控制定时和格式转换
  • I/O 端口是接口中 CPU 可访问的寄存器
  • I/O 端口有独立编址和统一编址两种方式
  • 总线由数据、地址和控制信号组成,现代趋势是点对点、串行、高速
  • 总线带宽取决于宽度、传输率和每次传送所需周期
  • 程序查询方式简单但 CPU 占用率高
  • 中断方式让 CPU 和外设并行,但数据传送仍由 CPU 完成
  • DMA 方式让高速外设和主存直接交换数据
  • DMA 结束仍要用中断通知 CPU
  • 操作系统通过系统调用、驱动程序和中断服务程序管理 I/O

理解 I/O 系统时,可以一直抓住三类信息:

  • 命令:CPU 要设备做什么
  • 状态:设备现在能不能做、有没有错
  • 数据:主机和设备真正交换的内容

I/O 接口、端口编址、中断和 DMA 都是围绕这三类信息组织起来的。

$ discussion
# Comments
waline
On this page
计组学习笔记6