总线、中断、DMA 与存储设备¶
I/O 的根本困难¶
设备种类多、速度跨度大、事件到达时间不可预测。CPU 不能为每种设备接一套专用指令和线路,也不应以纳秒级循环等待毫秒级设备。I/O 子系统通过统一接口、异步通知和批量搬运解耦双方。
设备控制器与内存映射 I/O¶
设备控制器把具体协议封装为少量寄存器:状态、命令和数据。内存映射 I/O 把这些寄存器放进物理地址空间,CPU 可用普通 load/store 访问。
这简化了 ISA,却不能把设备寄存器当普通内存优化:某次读取可能清除状态,写入顺序可能有意义,cache 和乱序执行必须受限制。
总线与互连¶
传统总线共享地址、数据和控制线:
- 地址说明访问目标;
- 数据线承载内容;
- 控制线说明读写、大小、响应和错误;
- 仲裁器决定多个主设备谁先使用互连。
共享总线简单,但设备增多后带宽和电气负载受限。现代片上网络和点到点链路提供更多并行通道,本质上仍需路由、流控、仲裁和顺序规则。
轮询:最简单的同步¶
CPU 反复读取状态寄存器:
轮询实现简单、响应时间可预测,适合事件极频繁或极短等待;若设备很慢,大量 CPU 周期被浪费。操作系统也会混合使用:低负载靠中断,高吞吐网络在一轮中断后批量轮询,减少频繁切换。
中断:设备主动通知¶
设备就绪后提出中断请求。处理器通常在可中断边界:
- 保存必要的当前执行位置和状态;
- 根据中断号找到处理程序;
- 提升或屏蔽相应优先级;
- 执行短小的中断服务例程;
- 恢复并继续原程序。
中断把等待时间还给 CPU,但有保存现场、流水线扰动和 cache 污染开销。中断合并可减少次数,却增加单个事件等待延迟。
中断与异常都改变控制流。区别在于异常通常由当前指令同步触发,中断来自外部并与当前指令异步。
DMA:让设备直接搬大块数据¶
若每个字节都由 CPU load 后再 store,CPU 会成为搬运工。DMA 控制器接收源地址、目的地址、长度与方向后,作为总线主设备直接在设备和内存间传输,完成后再中断 CPU。
DMA 的收益是降低指令开销并支持突发传输;代价包括:
- 与 CPU 竞争内存带宽;
- 需要固定、映射或描述缓冲区;
- 非一致 DMA 系统中要清理或失效 cache;
- 在支持 IOMMU 的系统中,需要正确限制设备可访问的地址,避免越权;缺少 IOMMU 时只能依赖总线防火墙、受信设备或其他平台机制,隔离能力通常更弱。
中断和 DMA 不是替代关系:DMA 搬数据,中断报告完成或错误。
HDD:机械运动主导延迟¶
硬盘访问包括寻道、旋转等待和传输:
随机访问频繁移动磁头,延迟高;连续大块读写摊薄机械开销,带宽更好。调度器会合并与排序请求,但过度排序可能损害公平性和请求时延。
SSD:没有磁头,但并非“无限快内存”¶
NAND flash 按页读写、按更大的擦除块擦除,且单元擦写次数有限。闪存转换层(FTL)把逻辑块地址映射到物理页,通过异地写、垃圾回收和磨损均衡管理介质。
因此 SSD 仍有特性:
- 读通常快于写,擦除最慢;
- 随机小写会触发写放大;
- 空闲空间和 TRIM 有助于垃圾回收;
- 多通道并行提高带宽,队列深度影响利用率;
- 尾延迟会因回收和磨损均衡波动。
外设访问的完整例子¶
网卡接收一帧时,可先用 DMA 把数据写入驱动准备的内存环形缓冲区,再更新完成描述符并触发中断。驱动确认描述符、把数据交给网络栈,并补充新缓冲区。这里同时出现设备寄存器、内存顺序、DMA、cache 一致性和中断。
自测¶
- 轮询和中断分别在哪类事件频率下更合适?
- DMA 为什么减少 CPU 指令,却不能减少内存带宽占用?
- HDD 与 SSD 随机访问代价的物理来源分别是什么?