跳转到内容

I/O、总线与存储设备

CPU 与外设速度相差几个数量级,交互靠总线、内存映射 I/O、中断与 DMA四套机制。本章讲这些机制如何工作,以及 HDD 与 SSD 在随机/顺序访问上的巨大差异如何影响文件系统与数据库设计(→ 存储层次与缓存)。

  • 总线与内存映射 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 等机制在忙时切回轮询。

机械硬盘的延迟由**寻道(磁头移动)+ 旋转(等扇区转到磁头下)**主导,一次随机访问约 5–10 ms;顺序读则接近介质带宽。因此:

  • 随机 I/O 与顺序 I/O 相差百倍以上——"顺序写比随机写快在任何介质上都成立",在 HDD 上尤其极端;
  • 文件系统尽量把相关块放在连续磁道,数据库把日志做成顺序追加。

SSD 以 NAND 闪存存储,读以页(几 KB)为单位,延迟约几十微秒——比 HDD 快百倍。但写入有三个结构性约束:

  1. 先擦后写:页只能从 1 写成 0,整体清零必须以块(几百 KB~几 MB)为单位擦除;
  2. 写放大(WAF):更新一页要把整个块的存活数据搬走再擦再写,实际写入量大于逻辑写入量;
  3. 磨损均衡与垃圾回收:闪存有擦写寿命,FTL(闪存转换层)要做磨损均衡;GC 与写放大是 SSD 写入变慢的原因——SSD 的写放大与垃圾回收使得持续随机写时性能骤降。

工程结论:

  • 顺序写仍优于随机写(对齐擦除块、减少写放大),SSD 上差距小了但没有消失;
  • 留白(over-provisioning)与 TRIM 让 FTL 有整理空间,长期满盘会显著变慢;
  • 是否 fsync、以什么粒度写,对 SSD 仍然是性能决定因素(→ 文件系统)。

存储介质的物理特性一路向上泄漏(→ 抽象泄漏):

  • 日志结构:HDD 想要顺序写,SSD 想要大块顺序写——日志(WAL、LSM 树、日志文件系统)成为共同答案(→ 日志与恢复、索引与 B+ 树);
  • 批量与预读:既然单次 I/O 贵,就合并小 I/O、提前读相邻块;
  • 缓存无处不在:设备缓存、页缓存、数据库缓冲池,各自假设下一层更慢。
  • MMIO 用普通访存指令读写设备;中断把轮询变成事件通知;DMA 让搬运不占 CPU
  • 高负载下中断开销反转优势:忙时切回轮询(NAPI)
  • HDD 随机访问由寻道+旋转主导,随机/顺序相差百倍
  • SSD 先擦后写,写放大与 GC 使持续随机写骤降;顺序写在任何介质上都更优
  • 介质特性向上泄漏:日志结构、批量 I/O、多层缓存都是对它的回应