I/O、总线与存储设备
CPU 与外设速度相差几个数量级,交互靠总线、内存映射 I/O、中断与 DMA四套机制。本章讲这些机制如何工作,以及 HDD 与 SSD 在随机/顺序访问上的巨大差异如何影响文件系统与数据库设计(→ 存储层次与缓存)。
CPU 与外设的对话
Section titled “CPU 与外设的对话”- 总线与内存映射 I/O(MMIO):外设的寄存器被映射到物理地址空间,CPU 用普通 load/store 指令读写设备——"写设备寄存器"就是"写某个特殊地址"。端口 I/O(x86 的
in/out)是旧式替代。 - 轮询 vs 中断:轮询让 CPU 反复读状态位,简单但浪费;中断让设备在就绪时打断 CPU,控制器保存现场、跳到中断处理程序、再恢复。中断是"事件通知"的硬件形态,网络收包、磁盘完成都靠它(→ I/O 模型与事件驱动)。
- DMA(直接内存访问):大数据搬运不让 CPU 逐字节复制,而是 CPU 告诉 DMA 控制器"把这段数据从设备搬到这个内存地址",搬完发一个中断。DMA 让数据搬运不占用 CPU——磁盘 I/O 与网络包都是 DMA 进内存的,CPU 只处理就绪后的数据。
中断 vs 轮询的工程选择在高负载下反转:每包一个中断的 overhead 会压垮内核,NAPI 等机制在忙时切回轮询。
HDD:机械的随机访问
Section titled “HDD:机械的随机访问”机械硬盘的延迟由**寻道(磁头移动)+ 旋转(等扇区转到磁头下)**主导,一次随机访问约 5–10 ms;顺序读则接近介质带宽。因此:
- 随机 I/O 与顺序 I/O 相差百倍以上——"顺序写比随机写快在任何介质上都成立",在 HDD 上尤其极端;
- 文件系统尽量把相关块放在连续磁道,数据库把日志做成顺序追加。
SSD:没有磁头,但有写放大
Section titled “SSD:没有磁头,但有写放大”SSD 以 NAND 闪存存储,读以页(几 KB)为单位,延迟约几十微秒——比 HDD 快百倍。但写入有三个结构性约束:
- 先擦后写:页只能从 1 写成 0,整体清零必须以块(几百 KB~几 MB)为单位擦除;
- 写放大(WAF):更新一页要把整个块的存活数据搬走再擦再写,实际写入量大于逻辑写入量;
- 磨损均衡与垃圾回收:闪存有擦写寿命,FTL(闪存转换层)要做磨损均衡;GC 与写放大是 SSD 写入变慢的原因——SSD 的写放大与垃圾回收使得持续随机写时性能骤降。
工程结论:
- 顺序写仍优于随机写(对齐擦除块、减少写放大),SSD 上差距小了但没有消失;
- 留白(over-provisioning)与 TRIM 让 FTL 有整理空间,长期满盘会显著变慢;
- 是否 fsync、以什么粒度写,对 SSD 仍然是性能决定因素(→ 文件系统)。
对上层设计的影响
Section titled “对上层设计的影响”存储介质的物理特性一路向上泄漏(→ 抽象泄漏):
- 日志结构:HDD 想要顺序写,SSD 想要大块顺序写——日志(WAL、LSM 树、日志文件系统)成为共同答案(→ 日志与恢复、索引与 B+ 树);
- 批量与预读:既然单次 I/O 贵,就合并小 I/O、提前读相邻块;
- 缓存无处不在:设备缓存、页缓存、数据库缓冲池,各自假设下一层更慢。
- MMIO 用普通访存指令读写设备;中断把轮询变成事件通知;DMA 让搬运不占 CPU
- 高负载下中断开销反转优势:忙时切回轮询(NAPI)
- HDD 随机访问由寻道+旋转主导,随机/顺序相差百倍
- SSD 先擦后写,写放大与 GC 使持续随机写骤降;顺序写在任何介质上都更优
- 介质特性向上泄漏:日志结构、批量 I/O、多层缓存都是对它的回应