第 4 章 处理器 (The Processor)

      +

      核心结论

      • 数据通路 (datapath):执行一条指令所需的所有功能单元(PC / RF / ALU / MEM)的连接。

      • 单周期实现:每条指令 1 个周期;CPI = 1;时钟周期 = 最长指令周期;硬件浪费但简单。

      • 流水线:把指令执行拆为 5 段(IF / ID / EX / MEM / WB),每段 1 个周期;理想 CPI = 1、实际 CPI 接近 1;吞吐量大但有冒险。

      • 数据冒险:RAW(Read After Write);用转发(forwarding)+ 停顿(stall)解决。

      • 控制冒险:分支延迟;用分支预测 + 延迟槽 + 静态分支预测解决。

      • 异常:中断 / 故障 / 陷阱;需要保存 PC + 跳转异常处理程序。

      本章主旨

      本章是计算机体系结构的核心——CPU 微架构。从单周期实现到 5 级流水线,再到转发 / 停顿 / 分支预测——理解本章才能理解现代 CPU 如何做到 IPC > 1、频率 > 5 GHz。后续章节的内存层级(第 5 章)与并行(第 6 章)都建立在 CPU 微架构基础上。

      一、核心概念

      本章围绕 6 个核心概念展开:从数据通路出发,介绍单周期实现,扩展到 5 级流水线,最后讨论数据冒险 / 控制冒险 / 异常处理。

      概念 定义 + 重要性 实现提示

      数据通路 (datapath)

      执行指令所需功能单元的连接;包含 PC / 寄存器堆 / ALU / 数据 / 指令存储器。

      §4.3;CPU 设计的"骨架"。

      单周期实现

      每条指令 1 个周期;CPI = 1;时钟周期 = 最长指令(通常 LDUR)。

      §4.4;教学起点,硬件浪费但简单。

      5 级流水线

      IF / ID / EX / MEM / WB;理想 CPI = 1;吞吐量为单周期 5 倍。

      §4.5-§4.6;现代 CPU 的标准结构。

      数据冒险 (hazards)

      RAW:后续指令依赖前指令未写回的结果;用 转发 + 停顿 解决。

      §4.7;编译器调度(指令重排)也可缓解。

      控制冒险

      分支延迟:取指时不知分支方向;用 分支预测 + 延迟槽 解决。

      §4.8;现代 CPU 分支预测精度 > 95%。

      异常

      中断 / 故障 / 陷阱;保存 PC + 状态 + 跳异常处理程序;返回用 ERET

      §4.9;OS / 中断处理的基础。

      二、详细笔记

      2.1 数据通路 (Datapath)

      What:执行指令所需功能单元的连接。

      Why:CPU 的"骨架"——理解数据通路才能理解指令执行流程与冒险检测。

      How

      数据通路组件(§4.3):

      • PC:程序计数器。

      • 指令存储器:根据 PC 取指令。

      • 寄存器堆:32 个 64-bit 寄存器;2 读 1 写端口。

      • ALU:算术逻辑单元(加 / 减 / 与 / 或 / 比较 / 移位)。

      • 数据存储器:load / store 访问。

      • 符号扩展:12-bit 立即数扩展为 64-bit。

      数据通路 vs 控制通路
      • 数据通路:搬运数据(PC / 寄存器 / 内存 / ALU)。

      • 控制通路:产生控制信号(ALUop / RegWrite / MemRead / MemWrite / Branch)。 两者共同构成 CPU。

      When:CPU 微架构设计;性能分析;debug 流水线 stall。

      ExampleLDUR X1, [X2, #40] 数据通路:PC → 指令存储器 → 寄存器堆读 X2 → 符号扩展 +40 → ALU 加 → 数据存储器读 → 寄存器堆写 X1。

      2.2 单周期实现 (Single-Cycle Implementation)

      What:每条指令 1 个周期;CPI = 1;时钟周期 = 最长指令周期。

      Why:最简单的 CPU 实现;教学起点;理解指令执行的"全貌"。

      How

      单周期时序(§4.4):

      • 上升沿:PC 锁存新地址。

      • 整个周期:取指、译码、读寄存器、ALU 算、访问内存、写回。

      • 下降沿:PC 加 4(准备下一条)。

      时钟周期:

      \[T_{\text{clk}} = \max(T_{\text{LDUR}}, T_{\text{ADD}}, T_{\text{B}}) \end{bmatrix>\]

      LDUR 通常最长(5 个功能单元串联),约 5 ns。

      单周期的工程权衡
      • 优点:CPI = 1 最简单;指令时序确定。

      • 缺点:时钟周期 = 最长指令,硬件浪费;功能单元不能复用。

      • 现代 CPU 几乎不用单周期(除极简微控制器)。

      When:教学;极简 CPU(嵌入式微控制器);理解指令时序。

      Example:MIPS 单周期 CPU 教科书实现;ARM Cortex-M0 微控制器。

      2.3 5 级流水线 (5-Stage Pipeline)

      What:把指令执行拆为 IF / ID / EX / MEM / WB 5 段;每段 1 个周期。

      Why:现代 CPU 标准结构;吞吐量为单周期 5 倍(理想 CPI = 1)。

      How

      5 段流水线(§4.5):

      • IF(Instruction Fetch):取指 + PC + 4。

      • ID(Instruction Decode):译码 + 读寄存器堆。

      • EX(Execute):ALU 运算 / 分支判断。

      • MEM(Memory Access):load / store 访问数据存储器。

      • WB(Write Back):写回寄存器堆。

      性能分析:

      • 理想 CPI = 1(每周期完成 1 条指令)。

      • 时钟周期 ≈ 单周期的 1/5(每段较短)。

      • 实际 CPI = 1 + 停顿(冒险)。

      流水线的"装填 / 排空"
      • 第 1 条指令:5 周期完成(IF → …​ → WB)。

      • 后续指令:每周期完成 1 条(流水线已"装填")。

      • 最后 1 条指令:5 周期完成(流水线"排空")。

      • N 条指令总时间 ≈ 5 + (N - 1) = N + 4 周期(远小于单周期的 N × 5)。

      When:所有现代 CPU 设计;性能优化目标。

      Example:ARM Cortex-A53 / Cortex-A57 / Intel Core i5 / i7 都是深度流水线(10-20 级)。

      2.4 数据冒险 (Data Hazards)

      What:RAW(Read After Write)——后续指令读寄存器时,前指令还没写回。

      Why:流水线必须解决冒险才能正确执行;理解冒险 = 理解 CPU 性能瓶颈。

      How

      转发(Forwarding,§4.7):

      • ALU 输出直接转发到下一条指令的 ALU 输入;不需要停顿。

      • 解决大部分 RAW。

      停顿(Stall / Bubble):

      • 当转发不能解决(如 load-use 冒险:紧接着 load 后的指令需要 load 结果),插入 1-2 个 bubble。

      • 流水线暂停 1-2 周期。

      编译器调度:

      • 编译器重排指令,插入无关指令避免冒险。

      • GCC -O2 -fno-schedule-insns 等。

      转发 vs 停顿的取舍
      • 转发 = 0 周期代价,但需要额外电路。

      • 停顿 = 1+ 周期代价,但简单。

      • 现代 CPU 用 转发 + 少量停顿 平衡。

      • load-use 冒险几乎不可避免(load 需要 2 周期才能转发)。

      When:CPU 微架构;编译器优化(指令调度);性能分析。

      ExampleADD X1, X2, X3; ADD X4, X1, X5 —— 第二条需要 X1,但 ADD 还在 EX 阶段;转发从 EX / WB 之间拉线解决。

      2.5 控制冒险 (Control Hazards)

      What:分支延迟——取指时不知分支方向,导致错误取指。

      Why:分支约占指令 20%;分支延迟对性能影响巨大。

      How

      分支预测策略(§4.8):

      • 静态预测:总是预测 taken / not-taken;简单但精度 ~50%。

      • 动态预测:用 2-bit 饱和计数器(局部 / 全局历史);精度 > 95%。

      • 延迟槽:编译器把分支前的指令调度到延迟槽执行(编译器必须填满)。

      错误预测代价:

      • 5 级流水线:错误预测 = 2-3 个周期代价(清空 IF / ID)。

      • 深度流水线(20 级):代价更大(10-20 周期)。

      分支预测的工程意义
      • 现代 CPU:分支预测精度 > 95%;乱序执行隐藏剩余 5% 代价。

      • 软件优化:用 __builtin_expect / 提示分支方向。

      • profile-guided optimization (PGO):运行时数据反馈给编译器。

      When:CPU 微架构;性能优化(分支预测器设计 / 软件提示)。

      Example:Intel Core i7 有 ~10K 项的全局分支历史表(BHB);分支预测精度 > 95%。

      2.6 异常 (Exceptions)

      What:中断 / 故障 / 陷阱——改变控制流的非预期事件。

      Why:OS / 中断处理的基础;理解异常才能理解 OS 与硬件交互。

      How

      异常类型(§4.9):

      • 中断(interrupt):外部异步事件(I/O 完成、时钟)。

      • 故障(fault):可恢复错误(缺页异常)。

      • 陷阱(trap):故意陷入(系统调用)。

      • 终止(abort):不可恢复错误(硬件故障)。

      异常处理流程:

      • 保存 PC + 状态寄存器到 supervisor 寄存器。

      • 跳转到异常处理程序(vector table)。

      • 处理完成返回(ERET 指令)。

      异常 vs 中断的命名
      • ARM / RISC-V:统一用 "exception",包括中断、故障、陷阱。

      • x86:用 "interrupt" 涵盖所有;细分"hardware interrupt" / "software interrupt" / "exception"。

      • OS 层:用 "trap" 涵盖所有进入内核的事件。

      When:OS 内核开发;中断处理程序;debug 程序崩溃。

      Example:Linux 系统调用用 SVC 指令触发陷阱;进入内核后查询 syscall table。

      三、关键图表

      视觉图表

      图 4-1
      Figure 1. 图 4-1:数据通路(单周期)
      图 4-2
      Figure 2. 图 4-2:5 级流水线时序图
      图 4-3
      Figure 3. 图 4-3:数据转发
      图 4-4
      Figure 4. 图 4-4:分支预测(2-bit 计数器)
      图 4-5
      Figure 5. 图 4-5:异常处理流程

      非可视化条目

      非可视化条目(表 / 算法)
      编号 内容摘要

      表 4.1

      LEGv8 指令 → 控制信号映射表(RegWrite / ALUop / MemRead / …​)。

      式 4-1 至 4-5

      性能公式、流水线吞吐率、停顿代价。

      列表 4.1-4.x

      LEGv8 流水线控制信号设计、转发路径、停顿检测。

      表 4.2

      ARM Cortex-A53 与 Intel Core i7 流水线对比(深度 / 频率 / 功耗)。

      核心公式对照表

      核心公式对照表
      概念 公式

      流水线吞吐率

      \(\text{Throughput} = \frac{1}{T_{\text{clk}} \cdot \text{CPI}_{\text{eff}}}\)

      停顿后 CPI

      \(\text{CPI} = 1 + \text{停顿周期数} / \text{指令数}\)

      转发延迟

      \(T_{\text{forward}} = 0 \text{(不计周期,但需额外电路)}\)

      分支预测错误代价

      \(\text{Cost} = \text{清空深度(典型 2-3)}\)

      四、思维导图

      mindmap
        root((第 4 章 处理器))
          数据通路
            PC
            寄存器堆
            ALU
            存储器
          单周期
            一指令一周期
            CPI为1
            时钟长
          5级流水线
            IFIDEXMEMWB
            理想CPI为1
            吞吐量x5
          数据冒险
            RAW
            转发
            停顿
          控制冒险
            分支延迟
            2bit预测器
            延迟槽
          异常
            中断故障陷阱
            保存PC
            ERET返回

      五、重点与易错点

      • 单周期 vs 流水线 vs 多核:单周期简单但慢;流水线适合高频;多核适合并行任务。

      • 转发不能解决所有 RAW:load-use 冒险必须停顿;现代 CPU 编译器尽量调度避免。

      • 分支预测精度 > 95%:但剩余 5% 仍有数周期代价;深度流水线(>10 级)损失更大。

      • 异常 ≠ 中断 ≠ 故障:RISC-V / ARM 统一叫 exception;x86 用 interrupt。

      • 流水线深度并非越深越好:深度增加 → 频率提高,但分支错误代价增大 → 净性能未必提升。

      • 乱序执行 (OoO):现代 CPU 在流水线之上加 OoO;用 保留站 + 重排序缓冲 (ROB) 解决数据冒险。

      • 超标量 (Superscalar):多发射(多条指令 / 周期);IPC > 1。

      • CPU 微架构决定性能:同频率的 i7 vs Zen 性能差 30%(微架构不同)。

      • 跨章衔接:第 5 章内存层级加速流水线停顿;第 6 章多核 + 多线程并行;附录 C 把微架构映射到硬件(CPLD / FPGA)。