目录
1.1 程序性能分析
1.1.1 性能公式
程序执行时间 = 总的指令数(工作量) × Cycles/Instruction(每条指令需要的时钟周期) × Seconds/cycle(每个时钟周期所需时间)
1.1.2 性能优化方向
- 总的指令数:优化算法,程序结构,编译优化
- Cycles/Instruction:增加IPC(单个周期能执行的指令数),处理器微架构设计,例如使用超标量设计
- Seconds/cycle:增加主频,减小周期
1.2 微架构设计权衡
1.2.1 设计权衡原理
在处理器微架构设计中,Cycles/Instruction (CPI) 与 Seconds/cycle(时钟周期) 之间存在重要的权衡关系:
1.2.2 简单微架构设计
例如:单周期CPU
- 特点一:一个周期内完成所有事情,因此 Cycles/Instruction (CPI) 较小
- 特点二:但是每个时钟周期会变长,即 Seconds/cycle 较大
优势:
- 指令执行简单直接
- 控制逻辑相对简单
- 每条指令的CPI = 1
劣势:
- 时钟周期必须足够长以完成最复杂的指令
- 主频较低
- 整体性能受限
1.2.3 复杂微架构设计
例如:多周期CPU或超标量处理器
- 特点一:一个周期内完成的事情较少,被拆分成多个流水级,因此 Cycles/Instruction (CPI) 较大
- 特点二:每个流水级电路变短,每个时钟周期变小,从而主频变高
优势:
- 时钟周期短,主频高
- 可以并行执行多条指令
- 整体吞吐量高
劣势:
- 控制逻辑复杂
- 需要处理数据相关性和控制相关性
- 功耗较高
1.2.4 微架构对比分析
微架构 | CPI | 时钟周期 | 特点 |
---|---|---|---|
单周期处理器 | 1 | 长 | 简单但主频低 |
流水线处理器 | 1 | 短 | 平衡性能和复杂度 |
超标量处理器 | <1 | 短 | 高性能但复杂 |
1.2.5 设计考虑因素
- 应用场景:根据目标应用选择合适的微架构
- 功耗要求:复杂微架构功耗更高
- 成本考虑:复杂微架构实现成本更高
- 性能需求:根据性能要求选择适当的复杂度
1.3 RISC-V微架构实现
RISC-V指令集的设计为微架构优化提供了良好的基础:
- 指令格式规整:便于流水线实现
- 寄存器数量适中:平衡性能和复杂度
- 模块化设计:支持不同复杂度的实现
- 可扩展性:支持从简单到复杂的各种实现
1.3.1 五级流水线架构
RISC-V处理器通常采用五级流水线设计,将指令执行分为五个阶段:
流水线阶段说明
-
取指令 (Fetch)
- 通过PC值从ROM中取指令
- 更新程序计数器PC
- 将指令存储到指令寄存器
-
译码 (Decode)
- 对指令进行解码
- 解析出指令类型、源寄存器、目标寄存器等
- 从寄存器堆读取操作数
-
执行 (Execute)
- 完成计算任务
- 算术逻辑单元(ALU)执行运算
- 处理立即数操作
-
访存 (Memory Access)
- 对于load/store指令访问内存
- 数据缓存操作
- 内存读写控制
-
写回 (Write Back)
- 把结果写入到寄存器堆
- 更新目标寄存器
- 为下一条指令准备数据
流水线执行流程图
开始
│
▼
┌─────────────┐
│ 取指令 │ ←─── PC指向下一条指令
│ (Fetch) │
└─────┬───────┘
│
▼
┌─────────────┐
│ 译码 │ ←─── 解析指令,读取操作数
│ (Decode) │
└─────┬───────┘
│
▼
┌─────────────┐
│ 执行 │ ←─── ALU运算,分支判断
│ (Execute) │
└─────┬───────┘
│
▼
┌─────────────┐
│ 访存 │ ←─── 内存读写操作
│ (Memory) │
└─────┬───────┘
│
▼
┌─────────────┐
│ 写回 │ ←─── 结果写入寄存器
│(Write Back) │
└─────┬───────┘
│
▼
结束
流水线并行执行示意图
时间轴: 0 1 2 3 4 5 6 7 8
│ │ │ │ │ │ │ │ │
指令1: 取指→译码→执行→访存→写回
指令2: 取指→译码→执行→访存→写回
指令3: 取指→译码→执行→访存→写回
指令4: 取指→译码→执行→访存→写回
指令5: 取指→译码→执行→访存→写回
说明: 每个时钟周期都有5条指令在不同阶段并行执行
1.3.2 超标量处理器 (Superscalar Processor)
超标量处理器定义
超标量处理器:具有两条或两条以上并行工作的流水线结构的处理器。
超标量处理器通过在同一时钟周期内发射多条指令来提高性能,是现代高性能处理器的重要特征。
指令执行方式
超标量处理器支持两种主要的指令执行方式:
-
顺序执行 (In-order)
- 指令按照程序顺序进入流水线
- 严格按照指令在程序中的顺序执行
- 实现简单,功耗较低
-
乱序执行 (Out-of-order)
- 指令可以乱序进入执行阶段
- 通过重排序缓冲区(ROB)保证程序语义正确性
- 性能更高,但实现复杂
执行方式对比
流水线阶段 | 顺序执行CPU | 乱序执行CPU |
---|---|---|
取指 (Fetch) | In-order | In-order |
译码 (Decode) | In-order | In-order |
发射&执行 (Issue & Execute) | In-order | Out-of-order |
写回 (Write Back) | In-order | Out-of-order |
提交 (Commit) | In-order | In-order |
双发射超标量顺序执行处理器架构
PC ──→ 取指令 ──→ 译码 ──→ 发射 ──→ 两条流水线
(Fetch) (Decode) (Issue) (Two Pipelines)
│
├─→ 执行&访存1──────────────────|
│ (Execute & Memory Access) |──→写回
│ | (Write Back)
└─→ 执行&访存2──────────────────|
(Execute & Memory Access)
架构特点:
- 双发射:每个时钟周期可以发射两条指令
- 顺序执行:指令按程序顺序进入执行阶段
- 并行流水线:两条独立的执行流水线并行工作
- 资源复用:共享取指、译码和写回阶段
超标量处理器优势
-
提高指令吞吐量
- 每个时钟周期处理多条指令
- 充分利用硬件并行性
-
提高资源利用率
- 多个功能单元并行工作
- 减少流水线空闲时间
-
保持程序语义
- 通过重排序保证结果正确性
- 支持数据依赖检测
-
适应现代应用
- 支持指令级并行(ILP)
- 提高整体系统性能
双发射超标量乱序执行处理器架构
PC ──→ 取指令 ──→ 译码 ──→ 发射 ──→ 两条流水线
(Fetch) (Decode) (Issue) (Two Pipelines)
│
├─→ 执行&访存1──────────────────|
│ (Execute & Memory Access) | ──→ 写回 ────→ ROB ──→ 提交
│ | (Write Back) (ROB) (Commit)
└─→ 执行&访存2──────────────────|
(Execute & Memory Access)
乱序执行关键组件:
-
寄存器重命名 (Register Renaming)
- 在译码阶段进行寄存器重命名
- 消除假数据依赖 (WAR和WAW依赖)
- 增加指令级并行性
-
重排序缓冲区 (ROB - Reorder Buffer)
- 存储乱序执行完成的指令
- 按程序顺序提交结果
- 保证程序语义正确性
-
双发射机制
- 每个时钟周期发射两条指令
- 两条并行流水线独立执行
- 支持指令级并行
乱序执行流程:
- 取指阶段:按程序顺序取指令
- 译码阶段:指令译码 + 寄存器重命名
- 发射阶段:检查资源可用性,发射指令
- 执行阶段:乱序执行,利用数据流并行性
- 写回阶段:结果写入重排序缓冲区
- 提交阶段:按程序顺序提交结果
乱序执行优势:
- 提高指令级并行性:消除假数据依赖
- 充分利用硬件资源:多条指令并行执行
- 提高性能:突破程序顺序限制
- 保持正确性:通过ROB保证程序语义
1.3.3 流水线设计原则与优势
流水线设计原则
- 时间平衡:流水线每个阶段所需时间相近
- 重复执行:流水线每个阶段操作会被重复执行
- 独立操作:流水线每个操作相互独立互不干扰
- 数据流控制:通过寄存器隔离各阶段,避免数据冲突
- 控制流处理:处理分支指令和异常情况
流水线优势
- 提高吞吐量:理想情况下每个时钟周期完成一条指令
- 提高主频:每个阶段电路更简单,时钟周期更短
- 资源利用率高:多个功能单元并行工作
- 性能可预测:执行时间相对稳定