← Back to Learning Notes

Lecture 21:知识 - 指令流水线

Chinese-language Computer Science 408 note: Lecture 21:知识 - 指令流水线. Original source available where applicable.

On this page

This note is currently available in Chinese. The original wording, formulas and diagrams are preserved to avoid an unverified technical translation.

描述:流水线把一条指令分段,让多条指令在不同段重叠执行,提升吞吐率而非单条延迟。核心计算是装入/排空时间,核心难点是结构、数据、控制三类冒险。

5.1 基本概念与性能

一条指令可分为取指、译码/取数、执行等阶段;在流水线中,后一条在前一条进入下一段后即可进入前一段。段间的流水线寄存器(流水线站/锁存器)保存本段结果并隔离时序。

原资料的三阶段重叠例。 设每条指令依次经过取指、分析、执行三个阶段,每阶段均耗时 $t$,共执行 $n\ge1$ 条指令;暂不计段间寄存器开销、资源冲突及数据/控制冒险。三种安排的区别是相邻指令的启动间隔:

安排 相邻指令启动间隔 完成 $n$ 条指令的时间
顺序执行,阶段不重叠 $3t$ $3nt$
一次重叠:上一条执行时,下一条取指 $2t$ $3t+(n-1)2t=(2n+1)t$
二次重叠:三段可同时处理不同指令 $t$ $3t+(n-1)t=(n+2)t$

$n=1$ 时三者都需 $3t$;当 $n$ 较大时,二次重叠才趋近于每 $t$ 完成一条。这里的“重叠”只提高多条指令的总体吞吐率,不把单条指令的三段执行时间缩短。

$$T_{clk}=\max(\text{各流水段组合逻辑延迟})+\text{流水段寄存器延迟}$$

  • 例如五段逻辑延迟为 80、50、50、70、50,段寄存器延迟 20,则时钟周期至少为 $80+20=100$。
  • 有利于流水:指令长度和格式规整、指令/数据对齐、源寄存器字段位置固定、采用 Load/Store 风格(仅 Load/Store 访问内存)。

5.1.1 吞吐率、加速比、效率

设 $k$ 段理想均衡流水线,段周期为 $\Delta t$,完成 $n$ 个任务:

$$ \begin{aligned} T_n&=(k+n-1)\Delta t\ TP&=\frac{n}{(k+n-1)\Delta t},\quad TP_{max}=\frac{1}{\Delta t}\ S&=\frac{kn\Delta t}{(k+n-1)\Delta t}=\frac{kn}{k+n-1}\ E&=\frac{n}{k+n-1} \end{aligned} $$

  • $n\to\infty$ 时理想吞吐趋于每周期一项、加速比趋于 $k$、效率趋于 1;短任务会受装入和排空时间明显影响。
  • 无阻塞基本流水线稳态 $CPI=1$。若主频 $f$、执行 $n$ 条指令共 $k+n-1$ 周期,实际吞吐为 $f\times n/(k+n-1)$。

例:4 级流水线的实际吞吐率。 某 4 级流水线主频为 $1.03\ \text{GHz}$,连续执行 100 条指令且无任何阻塞。装入第一条指令需 4 个周期,随后每周期完成 1 条,因此

$$ N_{cycle}=4+(100-1)=103 $$

$$ TP=\frac{100}{103/(1.03\times10^9)} =1.03\times10^9\times\frac{100}{103} =1.0\times10^9\ \text{条指令/s} $$

这里不能直接把主频 $1.03\ \text{GHz}$ 当作这 100 条指令的平均吞吐率,因为有限指令序列仍有装入和排空开销。

5.2 五段式 RISC 流水线

阶段 名称 主要工作
IF Instruction Fetch 由 PC 从指令 Cache 取指到 IF/ID 锁存器
ID Decode / Register Fetch 译码、读通用寄存器,立即数送 Imm,结果进 A/B 锁存器
EX Execute / Address ALU 运算、比较或计算有效地址
M Memory 访问数据 Cache,或处理部分 PC 更新
WB Write Back 将结果写回通用寄存器

三条互不相关指令在理想五段流水线中的装入、稳态与排空可画成:

指令/周期 1 2 3 4 5 6 7
I1 IF ID EX M WB
I2 IF ID EX M WB
I3 IF ID EX M WB

第一条要经过 5 个周期才完成,此后理想稳态每周期完成一条;因此提高的是长期吞吐率,单条指令延迟并未缩短。

5.2.1 各类指令流动

指令 ID EX M WB
运算 ADD Rs,Rd 读寄存器 ALU 算术 空段 结果写 Rd
Load LOAD Rd,off(Rs) Rs 到 A、偏移到 Imm $EA=Rs+off$ 数据 Cache 读 数据写 Rd
Store STORE Rs,off(Rd) 基址到 A、数据到 B、偏移 Imm 算 EA B 写数据 Cache 空段
条件转移 beq/bne 两操作数到 A/B,偏移 Imm 比较 写目标 PC 空段
无条件 jmp 偏移 Imm 直接写目标 PC 空段 空段
  • 典型 Load/Store 型 RISC 中,只有 Load/Store 显式访问数据存储器;每条指令仍须在 IF 段访问指令 Cache/存储器。运算指令的 M 段可能空置但仍占用一个流水时钟,以保持五段结构规整。
  • 源 PDF 的定长指令模型把分支立即数按“指令条数”编码,故目标为 $PC+\text{指令字长}+\text{偏移}\times\text{指令字长}$。若某 ISA 直接给字节位移,则不再额外乘指令字长,应以题设编码为准。材料模型中条件分支 PC 在 M 段更新,而无条件跳转可在 EX 段更新,故控制代价不同。

5.3 三类冒险

5.3.1 结构冒险

多条指令同一时刻争用同一硬件资源,例如 IF 取指与 M 段访存共用单端口存储器。

  • 处理:暂停相关指令插入气泡,或复制资源(分离指令/数据存储器或 I-Cache/D-Cache)。本质是解决互斥资源不足。

5.3.2 数据冒险

后一指令依赖前一指令尚未产生/写回的结果。处理方法:

相关类型 含义 在简单顺序五段流水中的情况
RAW(写后读) 后指令要读前指令尚未写出的值 真相关,是本讲最主要的数据冒险
WAR(读后写) 后指令先写,破坏前指令尚未完成的读 顺序发射、顺序读写时通常不会出现;乱序执行需处理
WAW(写后写) 两条指令写同一位置但完成顺序颠倒 顺序完成时通常不会出现;乱序/多发射需处理

不要把“寄存器名相同”一律判成必须停顿:先判断读写方向、结果何时可用、是否已有转发,以及处理器是否允许乱序。

方法 要点
等待/阻塞 硬件 stall 或软件插 nop,直到数据可用
数据旁路/转发 将 ALU 输出直接送到后续 ALU 输入,不必等 WB
编译调度 把无依赖指令移入间隙

例:无转发且寄存器不能同周期读写时的前端阻塞。 按序五段流水线依次执行:

I1: LOAD  R1, [a]
I2: LOAD  R2, [b]
I3: ADD   R1, R2
I4: STORE R2, [x]
  • I3 在 ID 段需要读取 R1 和 R2,分别依赖 I1、I2 的写回,属于两个 RAW 相关。由于无转发,且题设不允许寄存器在同一周期先写后读,I3 必须等到较晚的 I2 完成 WB 之后的下一周期才能完成 ID。
  • 本题 ADD R1,R2 的目标寄存器是 R2,即 R2←R1+R2;I4 要把新的 R2 写入 [x],所以 I3→I4 也有 RAW 相关。I4 不能提前进入 ID 是为了等 I3 的结果,而它最初不能提前进入 IF,则是因为 I3 阻塞时占着 IF/ID 流水寄存器;这两个原因不能混为一谈。
  • 与原 PDF 第 22 页的时序表一致,在“按序发射、按序完成、无转发且同周期不可先写后读”的模型中:
指令 IF ID EX M WB 中间等待
I1 1 2 3 4 5 无
I2 2 3 4 5 6 无
I3 3 7 8 9 10 第 4–6 周期等待 I1、I2 写回
I4 7 11 12 13 14 第 8–10 周期等待 I3 写回

因此 I3 的 ID 到第 7 周期才开始,I4 的 IF 也只能从第 7 周期开始;I4 的 ID 还要等到 I3 在第 10 周期完成 WB 之后的第 11 周期。

另一个源例:判断真正的数据依赖。 原 PDF 第 10–11 页给出如下四条指令:

I1: add   s2, s1, s0   # s2 ← s1+s0
I2: load  s3, 0(t2)    # s3 ← M[t2]
I3: add   s2, s2, s3   # s2 ← s2+s3
I4: store s2, 0(t2)    # M[t2] ← s2

I1→I3 对 s2、I2→I3 对 s3、I3→I4 对 s2 都有 RAW 相关;I2 与 I4 没有寄存器 RAW 相关,因为前者写 s3,后者读 s2 和 t2。两者确实访问同一内存地址,且顺序是先读后写;若处理器允许访存乱序,仍须保持这一内存先后语义。但在本题的按序五段流水线中,它不构成需要停顿的寄存器数据冒险。

  • 旁路不能消除所有冲突:典型 load-use 中数据到 M 末才可用,紧随的使用者仍常需停 1 周期。
  • 插入足够 nop 一定可从正确性上消除数据冒险,但会降低吞吐;是否能交换指令必须保证程序语义不变。

5.3.3 控制冒险

分支、跳转、异常或中断改变 PC,使已经按顺序取入的指令可能无效。

处理方向 例子
停顿/冲刷流水线 等分支确定后再取正确路径
尽早形成结果 提前比较/计算目标地址
分支预测 静态预测或动态预测;错误后冲刷错误路径
预取 预取可能的目标/顺序路径指令
  • 异常检测可分布在不同段:无效指令在 ID、算术溢出在 EX、指令地址问题在 IF、数据地址问题在 EX 或 M。发现异常的那条指令是发生异常的指令,后续已进入流水线的指令须清除或阻塞。
  • 外部中断可在 IF 前检测以尽早进入服务程序,或在 WB 等边界检测以保证精确状态;检测位置影响需冲刷的指令数。
  • 对精确异常,异常指令之前的更老指令应完成,异常指令及其之后的年轻指令不得把不应提交的结果留在体系结构状态中;仅说“发现后全部清空”会漏掉这一先后边界。

5.4 流水线分类与多发技术

分类维度 类型 含义
使用级别 部件功能级 把复杂运算(如浮点加法的求阶差、对阶、尾数加、规格化)分段
处理机级 把一条指令分为 IF/ID/EX/M/WB 等
处理机间级 多处理机各做专门任务,经共享存储传递结果
功能 单功能 / 多功能 只能一种固定功能 / 可通过不同连接实现多种功能
同时连接 静态 / 动态 同时各段只按一种连接工作 / 可同时以不同连接完成不同运算
技术 特点
超标量 一个时钟周期发射多条独立指令,需要多个功能部件,可配合动态调度
超流水 把一个时钟周期再细分,在不同时间点发射多条,功能部件一个周期可多次使用
VLIW 编译器把可并行操作编码进包含多个 OP 字段的超长指令字,执行时分开执行
  • 超标量/超流水/VLIW 均需要足够独立性和编译/硬件调度,不能随意颠倒有依赖指令。

题型:#流水线计算与冒险

  1. 先确定段数 $k$、时钟周期 $\Delta t$、任务数 $n$ 和是否阻塞;无阻塞总周期为 $k+n-1$。
  2. 若给各部件延迟,取最大段延迟并加流水寄存器延迟;不要把所有段延迟相加当作流水时钟。
  3. 画时空表追踪每条指令的 IF/ID/EX/M/WB,资源同列冲突是结构冒险,读到未写回/未转发值是数据冒险,PC 未确定造成错误路径是控制冒险。

相关知识

5.5 本节复盘

  • 流水线通过阶段重叠提升吞吐,理想总时间 $(k+n-1)\Delta t$,长期 $CPI\to1$。
  • 五段为 IF、ID、EX、M、WB;运算类、Load、Store、分支在 M/WB 的工作不同。
  • 结构冒险靠停顿或资源复制,数据冒险靠 stall/nop、旁路、编译调度,控制冒险靠停顿、提前判断、预测/预取。
  • 时钟周期由最慢段和段寄存器延迟决定;浮点/处理机级/处理机间均可形成流水,超标量、超流水、VLIW 是提高并行发射的不同路径。