前置复习:数据通路修改与性能分析
1. 修改数据通路的四步法
给现有 CPU 增加指令时,先从指令效果出发,再考虑连线与编码:
- 写 RTL 语义(register-transfer-level semantics):读取什么,计算什么,最后更新哪些寄存器/内存/PC。
- 对照当前数据通路(datapath):每个所需值是否存在,能否到达目的端,当前周期是否可用。
- 补充 MUX、线路或运算单元:增加新来源时通常扩展输入选择;运算资源不够时再增设硬件。
- 列控制信号及取值:包括选择、使能、ALU 操作、立即数类型、访存宽度和下一 PC。
RTL 中的箭头表示架构状态更新,不是按书写顺序逐条执行的软件语句。例如 jal/jalr 的目标与链接地址都由更新前的值计算。
先写出每类指令的状态变化
下表假设 32 位指令,顺序下一 PC 为 P+4,P 是当前指令地址,所有运算按 XLEN 截断:
| 指令 | 主要 RTL 效果 |
|---|---|
add rd,rs1,rs2 |
R[rd]←R[rs1]+R[rs2] |
addi rd,rs1,imm |
R[rd]←R[rs1]+sext(imm12) |
ld rd,off(rs1) |
EA←R[rs1]+sext(off12);R[rd]←Mem64[EA] |
sd rs2,off(rs1) |
EA←R[rs1]+sext(off12);Mem64[EA]←R[rs2] |
beq rs1,rs2,label |
R[rs1]=R[rs2] 时 PC←P+Bimm,否则 P+4 |
jal rd,label |
R[rd]←P+4;PC←P+Jimm |
jalr rd,off(rs1) |
R[rd]←P+4;PC←(旧 R[rs1]+sext(off12)) & ~1 |
lui rd,imm20 |
R[rd]←sext32(imm20<<12) |
auipc rd,imm20 |
R[rd]←P+sext32(imm20<<12) |
写 R[0] 被忽略。load 的符号/零扩展、store 的字节掩码应随访问宽度补进规格,不能把所有访存都视为 64 位。
2. 用语义填写控制表
下面明确采用一个单周期示例结构:独立 PC+4 加法器;主 ALU 可选 A=rs1/PC/0、B=rs2/imm;分支另有比较器;写回可选 ALU/内存/PC+4;jalr 的目标路径可清最低位。
| 指令类 | RegWrite | MemRead / MemWrite | ALU A / B | ALU 操作 | 写回来源 | 下一 PC |
|---|---|---|---|---|---|---|
| R 型 ALU | 1 | 0 / 0 | rs1 / rs2 | 按 funct 译码 | ALU | PC+4 |
| I 型 ALU | 1 | 0 / 0 | rs1 / I-imm | 按 funct 译码 | ALU | PC+4 |
| load | 1 | 1 / 0 | rs1 / I-imm | ADD | 内存 | PC+4 |
| store | 0 | 0 / 1 | rs1 / S-imm | ADD | — | PC+4 |
| branch | 0 | 0 / 0 | PC / B-imm | ADD | — | taken 时 ALU,否则 PC+4 |
| jal | 1 | 0 / 0 | PC / J-imm | ADD | PC+4 | ALU |
| jalr | 1 | 0 / 0 | rs1 / I-imm | ADD | PC+4 | ALU & ~1 |
| lui | 1 | 0 / 0 | 0 / U-imm | ADD | ALU | PC+4 |
| auipc | 1 | 0 / 0 | PC / U-imm | ADD | ALU | PC+4 |
“—”表示该来源不会被消费,但写使能必须明确为 0。表中用信号含义而非任意二进制编码;映射到题目的实际 MUX 编码时再填 0/1/多位选择值。RegWrite=1 也不改变 x0 恒为零的规则。
控制信号取决于结构。若原图用主 ALU 做 beq 的减法比较、另设分支目标加法器,则 beq 的 ALU 输入应为 rs1/rs2、操作为 SUB;不能直接照抄本表的 PC/B-imm。
例:增加 jalr
从 PC_next=(R[rs1]+imm)&~1 和 R[rd]=P+4 反推:
- ALU 若已有 load/store 的地址加法,可复用 rs1+I-imm。
- PC 输入 MUX 增加寄存器间接目标路径,并清 bit 0。
- 写回 MUX 增加 PC+4 来源;若已支持 jal,可复用。
- 控制器增加 jalr 译码,选 ADD、I-imm、PC+4 写回及间接跳转;禁止数据存储器读写。
- 检查目标路径延迟;增加 MUX 可能拉长关键路径(critical path),不能只检查逻辑功能。
流水化之后,这些控制值还必须随所属指令逐级保存,见流水线控制信号。
3. CPU 时间与 CPI
性能(performance)通常与执行时间成反比:
| 量 | 英文与含义 | 单位 |
|---|---|---|
| IC | instruction count,实际执行的动态指令数 | instruction / program |
| CPI | cycles per instruction,平均每条指令周期数 | cycle / instruction |
| \(T_{\mathrm{clk}}\) | clock period,时钟周期 | second / cycle |
| \(f_{\mathrm{clk}}\) | clock frequency,时钟频率 | cycle / second |
动态 IC 要计入循环的实际执行次数和伪指令展开,不能只数源程序行数。混合指令的平均 CPI 按指令比例加权:
例:50% 指令 CPI=1,30% 为 2,20% 为 3,则平均 CPI=1.7。若 IC=\(10^9\)、频率为 2 GHz:
比较新旧机器时统一用:
S>1 才是加速。降低 IC、降低 CPI、提高频率可能相互牵制;仅比较 GHz 或 CPI 不能决定程序谁更快。CPU 时间也不等于含 I/O 等待的总墙钟时间(wall-clock time)。
4. Amdahl 定律(Amdahl's Law)
原程序执行时间中,某部分占比 F,将该部分加速 k 倍,其他部分不变:
F 是优化前的时间比例,不是指令比例,也不是优化后的占比。这是将固定工作量拆成受影响与不受影响部分的性能模型,见 Cornell:Amdahl's law。
例如 40% 时间可加速 4 倍:
即使该部分无限快:
如果题目给的是指令比例 \(p_i\),在统一时钟周期下需先换成时间比例:
例如只有 20% 的指令属于某类,但 CPI=4,其他 80% 的 CPI=1,这类指令占原时间 \(0.2\times4/(0.2\times4+0.8)=50\%\),不能把 F 直接写成 20%。
解题时先固定程序/工作量与基准,再确认变化的是 IC、CPI、周期还是某部分耗时;流水线的吞吐率、启动开销和停顿分析见性能分析章节。