专栏文章
专栏文章
计算机原理专栏
1. 计算机原理专栏 #01:CPU 与指令执行 2. 计算机原理专栏 #02:存储体系 3. 计算机原理专栏 #03:IO 与总线 4. 计算机原理专栏 #04:内存模型

计算机原理专栏 #03:IO 与总线

发布于 2026-06-05 06:26 👁 12 次阅读
#computer-architecture#hardware

本文从 IO 控制方式出发,讲解总线结构、PCIe 协议、磁盘工作原理,深入分析顺序 IO vs 随机 IO 的性能差异,最终以零拷贝(sendfile/mmap)为例,展示底层硬件原理如何直接影响 Kafka、数据库等中间件的设计决策。

计算机原理系列CPU 与指令执行 · 存储体系 · 内存模型 · 相关:网络与 IO 模型 · ../../02 编程语言/02 Java/09 JVM 内存分区与 Linux 内存分配机制


目录

章节 说明
IO 控制方式 程序轮询/中断/DMA 三种演进
总线结构 地址/数据/控制总线与多总线架构
PCIe 协议 现代高速 IO 互联标准
磁盘工作原理 机械磁盘寻道模型与 SSD 原理
顺序 IO vs 随机 IO 性能差异的根本原因
零拷贝 sendfile/mmap 与 Kafka 的关系

IO 控制方式

CPU 与 IO 设备之间的数据传输,经历了三个发展阶段:

程序轮询(Polling)

CPU 主动循环查询 IO 设备的状态寄存器,等待数据就绪后再读取。

CPU: 查询状态 → 未就绪 → 查询状态 → 未就绪 → ... → 就绪 → 读取数据

缺点:CPU 在等待期间完全被占用,无法做其他事情,CPU 利用率极低。

中断驱动(Interrupt)

IO 设备完成操作后,向 CPU 发送中断信号,CPU 暂停当前任务,跳转到中断处理程序(ISR)处理 IO,完成后恢复原任务。

CPU 执行其他任务
        ↓ 收到中断信号
CPU 保存现场 → 执行 ISR → 恢复现场

优点:CPU 不再忙等,可以处理其他任务。
缺点:每传输一个字节/字都触发一次中断,中断开销(上下文切换)在大数据量传输时成为瓶颈。

DMA(Direct Memory Access)

引入 DMA 控制器(DMAC) 这一协处理器芯片,CPU 只需配置好"从哪里传到哪里、传多少",剩余的数据搬运完全由 DMAC 完成,CPU 可以去做其他事情,传输完成后 DMAC 发出一次中断通知 CPU。

CPU 配置 DMAC(源地址、目标地址、数据长度)
    ↓
DMAC 独立完成数据传输(硬盘 → 内存 / 内存 → 网卡)
    ↓
传输完成,DMAC 发中断通知 CPU

DMAC 的双重身份

适用场景

场景 说明
大数据量传输 千兆网卡、硬盘大文件读写,CPU 搬运忙不过来
低速 IO 数据传输很慢时,DMAC 等数据到齐再通知 CPU,避免 CPU 频繁轮询

现代计算机中,几乎每个外设(网卡、磁盘控制器、显卡)都内置了自己的 DMAC,CPU 已经很少直接参与数据搬运。


总线结构

为什么需要总线

如果 N 个设备两两直连,需要 N² 条线路,复杂度爆炸。总线通过共享线路将复杂度降为 N:所有设备连接到同一组线路,通过总线裁决(Bus Arbitration) 机制决定某一时刻谁可以使用总线。

三类总线信号线

线路类型 职责 类比
数据线(Data Bus) 传输实际数据内容 公交车上的"乘客"
地址线(Address Bus) 指定数据的目标地址 乘客的"目的站"
控制线(Control Bus) 传输读/写/中断等控制信号 司机的"指令"

多总线架构

现代计算机通常有多条总线,按速度分层:

CPU 核心
  ↕ 本地总线(Local Bus)/ 后端总线(Back-side Bus)
L3 Cache
  ↕ 前端总线(Front-side Bus)/ 系统总线(System Bus)
北桥芯片(现已集成进 CPU)
  ↕ 内存总线(Memory Bus)     ↕ I/O 总线(PCI/PCIe Bus)
主内存(DRAM)                  IO 设备(磁盘、网卡、显卡)

2008 年后 Intel 引入 QPI(Quick Path Interconnect) 替代前端总线,采用点对点串行高速互联,彻底消除前端总线带宽瓶颈。

总线在软件设计中的类比

总线的设计思想——共享通道 + 发布订阅——在软件中广泛应用:


PCIe 协议

PCIe(Peripheral Component Interconnect Express)是现代计算机中连接高速外设的标准总线协议。

核心特点

特性 说明
串行差分信号 取代并行总线,抗干扰能力强,频率更高
点对点连接 每个设备独享通道,无总线争用
Lane 可扩展 x1/x4/x8/x16,带宽线性扩展
全双工 上行和下行同时传输

带宽演进

版本 单 Lane 带宽 x16 带宽 典型应用
PCIe 3.0 ~1 GB/s ~16 GB/s 主流显卡、NVMe SSD
PCIe 4.0 ~2 GB/s ~32 GB/s 高端显卡、企业 SSD
PCIe 5.0 ~4 GB/s ~64 GB/s 数据中心 NVMe

NVMe SSD 通过 PCIe 直连 CPU,绕过传统 SATA 控制器,延迟可低至 ~100μs,IOPS 可达数十万。


磁盘工作原理

机械磁盘(HDD)

物理结构

部件 职责
盘面(Disk Platter) 磁性涂层存储数据,电机驱动旋转
磁头(Drive Head) 读写数据,每个盘面正反面各一个
悬臂(Actuator Arm) 控制磁头径向移动,定位到指定磁道

数据定位:磁道(Track)→ 扇区(Sector)→ 柱面(Cylinder,多盘面同一磁道的集合)

一次随机 IO 的时间 = 旋转延迟 + 寻道时间

时间组成 计算方式 7200 RPM 硬盘
平均旋转延迟 旋转半圈时间 = 1s / (RPM/60) / 2 ~4.17ms
平均寻道时间 悬臂移动到目标磁道 4~10ms
合计(IOPS) 1s / (旋转延迟 + 寻道时间) ~70~125 IOPS

机械磁盘 IOPS 约 100,而 CPU 每秒可执行 20 亿次操作,差距 2000 万倍

SSD(固态硬盘)

SSD 基于 NAND Flash 芯片,无机械结构:

特性 说明
无寻道延迟 随机读延迟 ~100μs,比 HDD 快 100 倍
高 IOPS 企业级 NVMe SSD 可达 100 万+ IOPS
写放大 Flash 需要先擦除再写入,以页(4KB)为写单位,以块(256KB~4MB)为擦除单位
磨损均衡 FTL(Flash Translation Layer)负责均匀分散写入,延长寿命
顺序写优化 预留 OP(Over-Provisioning)空间,合并小写请求为大块写

SSD vs HDD 对比

维度 HDD SSD(SATA) SSD(NVMe)
随机读 IOPS ~100 ~10 万 ~100 万
顺序读带宽 ~200 MB/s ~500 MB/s ~7 GB/s
随机读延迟 ~10ms ~100μs ~20μs
适用场景 冷数据归档 通用存储 数据库、高频交易

顺序 IO vs 随机 IO

性能差异的根本原因

机械磁盘:顺序 IO 只需一次寻道,然后磁头停在磁道上连续读取,吞吐率可达 200 MB/s;随机 IO 每次都需要重新寻道,IOPS 只有 ~100。

SSD:虽然没有机械寻道,但随机小写会触发写放大(擦除→写入),顺序写可以合并为大块写,效率更高。

对数据库的影响:为什么要顺序写日志

数据库(MySQL InnoDB、PostgreSQL 等)采用 WAL(Write-Ahead Logging) 机制:

事务提交流程:
1. 将变更顺序追加到 WAL 日志文件(顺序 IO,极快)
2. 返回客户端"提交成功"
3. 异步将脏页刷回数据文件(随机 IO,较慢)

顺序写日志的优势

对比维度 顺序写日志 随机写数据页
HDD IOPS 消耗 极低(追加写,无寻道) 高(每个脏页位置随机)
延迟 ~1ms ~10ms
可靠性 顺序日志易于重放恢复 随机写中断难以恢复

Kafka 的高吞吐也来源于此:消息追加到 Partition 文件末尾(顺序写),消费者按序读取(顺序读),充分利用了磁盘顺序 IO 的高带宽。


零拷贝

传统数据传输的四次拷贝

以"从磁盘读文件,通过网络发送"为例,传统方式需要 4 次数据传输:

磁盘
  ↓ DMA 拷贝(硬件完成)
内核读缓冲区(Page Cache)
  ↓ CPU 拷贝(软件完成)
用户空间应用缓冲区
  ↓ CPU 拷贝(软件完成)
内核 Socket 发送缓冲区
  ↓ DMA 拷贝(硬件完成)
网卡缓冲区 → 网络

其中 2 次 CPU 拷贝完全是在内存中"搬运数据",没有任何计算价值。

零拷贝:sendfile

Linux sendfile 系统调用(Java NIO FileChannel.transferTo())将数据路径优化为 2 次 DMA 拷贝,完全消除 CPU 拷贝:

磁盘
  ↓ DMA 拷贝
内核读缓冲区(Page Cache)
  ↓ DMA 拷贝(直接根据 fd 描述符写入)
网卡缓冲区 → 网络

性能提升:IBM 测试数据显示,零拷贝可将传输同等数据的时间缩短 65%,吞吐量提升约 3 倍

mmap(内存映射)

mmap 将文件直接映射到进程的虚拟地址空间,读取文件如同读内存,省去了用户空间与内核空间之间的一次 CPU 拷贝:

磁盘
  ↓ DMA 拷贝(缺页中断时触发)
内核 Page Cache(同时映射到进程虚拟地址空间)
  ↓ 进程直接访问(无需额外拷贝)
用户空间

Kafka 的零拷贝实现

// Kafka 源码(简化)
public long transferFrom(FileChannel fileChannel, long position, long count) {
    return fileChannel.transferTo(position, count, socketChannel);
    // 底层调用 Linux sendfile 系统调用
}

Kafka 消费者拉取消息时,消息数据从 Page Cache 直接通过 DMA 写入网卡,全程不经过 JVM 堆,这是 Kafka 能实现极高吞吐量的关键之一。

零拷贝技术对比

技术 系统调用 拷贝次数 适用场景
传统 read/write read + write 4 次(2 DMA + 2 CPU) 需要在用户空间处理数据
sendfile sendfile 2 次(2 DMA) 文件直接转发到网络,无需修改
mmap + write mmap + write 3 次(2 DMA + 1 CPU) 需要在用户空间修改数据后发送
sendfile + SG-DMA sendfile 2 次(2 DMA,无 CPU) 网卡支持 Scatter-Gather DMA

数据库顺序写日志 + Kafka 零拷贝,是两个最能体现"理解底层硬件原理才能做出正确架构决策"的经典案例。


参考资料

  • 《深入浅出计算机组成原理》— 极客时间,郑晔
  • Kafka: a Distributed Messaging System for Log Processing — Jay Kreps et al.
  • Efficient data transfer through zero copy — IBM Developer Works
  • 《计算机组成与设计:硬件/软件接口》— 第 5~6 章
← 返回列表

评论 (0)

暂无评论,来留下第一条吧。

发表评论