04

处理器

超标量与乱序执行

阅读量:1 · 预计 15 分钟读完

ILPTomasulo算法推测执行
阅读进度3%

第四章 处理器

导读

处理器是计算机系统的核心部件,负责执行指令和处理数据。处理器设计的优劣直接决定了计算机系统的性能、功耗和成本。从早期的单核处理器到现代的多核异构处理器,处理器设计经历了巨大的变革,但核心目标始终是:在功耗和面积的约束下,最大化性能。

本章将深入探讨处理器设计的关键技术,包括数据通路设计、控制单元实现、流水线处理器设计、超标量与乱序执行、以及现代处理器的各种优化技术。我们将从简单的单周期处理器开始,逐步构建出复杂的现代处理器,帮助读者理解处理器设计的演进过程和核心原理。

学习本章后,读者将能够:理解处理器数据通路和控制单元的设计方法;掌握流水线处理器的设计技术;了解超标量和乱序执行的工作原理;熟悉现代处理器的各种优化技术。

核心概念详解

4.1 处理器设计基础

4.1.1 处理器设计的核心目标

处理器设计需要在多个相互冲突的目标之间进行权衡:

性能(Performance)

  • 执行速度:单位时间内执行的指令数
  • 响应时间:完成单个任务的时间
  • 吞吐量:单位时间内完成的任务数

功耗(Power)

  • 动态功耗:与开关活动相关
  • 静态功耗:与漏电流相关
  • 功耗墙:功耗限制频率提升

面积(Area)

  • 芯片面积:影响成本和良率
  • 功能单元面积:ALU、缓存等
  • 互连面积:布线资源

可编程性(Programmability)

  • 指令集兼容性
  • 软件生态
  • 开发工具支持

4.1.2 处理器设计方法学

自顶向下设计

  • 从系统需求出发
  • 逐层分解为子模块
  • 先设计架构,再实现细节

自底向上设计

  • 从基本单元开始
  • 组合成复杂模块
  • 适合已有IP复用

参数化设计

  • 使用参数配置处理器
  • 支持不同性能点
  • 如RISC-V的不同实现

4.2 单周期处理器设计

单周期处理器是最简单的处理器实现方式,每条指令在一个时钟周期内完成执行。

4.2.1 数据通路设计

数据通路是处理器中执行指令的数据路径,包括功能单元和互连。

基本组件

程序计数器(PC)

  • 保存当前执行指令的地址
  • 每个周期更新为下一条指令地址

指令存储器

  • 存储程序指令
  • 根据PC提供指令

寄存器文件

  • 存储操作数和结果
  • 支持多端口读写
  • 通常有32个寄存器

算术逻辑单元(ALU)

  • 执行算术和逻辑运算
  • 支持加、减、与、或等操作

数据存储器

  • 存储程序数据
  • 支持load和store操作

符号扩展单元

  • 将立即数扩展到寄存器宽度
  • 支持有符号和无符号扩展

多路选择器

  • 选择不同的数据源
  • 由控制信号驱动

4.2.2 控制单元设计

控制单元根据指令生成控制信号,协调数据通路工作。

控制信号

RegDst

  • 选择写寄存器来源
  • R型指令:rd字段
  • I型指令:rt字段

ALUSrc

  • 选择ALU第二个操作数
  • 0:寄存器
  • 1:立即数

MemtoReg

  • 选择写回数据来源
  • 0:ALU结果
  • 1:内存数据

RegWrite

  • 是否写寄存器
  • 1:写
  • 0:不写

MemRead

  • 是否读内存
  • 1:读
  • 0:不读

MemWrite

  • 是否写内存
  • 1:写
  • 0:不写

Branch

  • 是否是分支指令
  • 1:是
  • 0:否

ALUOp

  • ALU操作类型
  • 00:load/store
  • 01:beq
  • 10:R型指令

控制逻辑实现

真值表

指令      RegDst  ALUSrc  MemtoReg  RegWrite  MemRead  MemWrite  Branch  ALUOp
R型       1       0       0         1         0        0         0       10
Load      0       1       1         1         1        0         0       00
Store     X       1       X         0         0        1         0       00
Branch    X       0       X         0         0        0         1       01

逻辑表达式

根据真值表推导每个控制信号的逻辑表达式,使用与门、或门、非门实现。

4.2.3 单周期处理器的优缺点

优点

  • 设计简单,易于理解和验证
  • 每条指令只执行一个周期
  • 不需要流水线寄存器

缺点

  • 时钟周期由最慢指令决定
  • 功能单元不能复用
  • 性能低下
  • 功耗高

时钟周期计算

  • 取指:200ps
  • 译码:100ps
  • 执行:300ps(最慢)
  • 访存:200ps
  • 写回:100ps
  • 总周期:900ps

即使简单指令(如寄存器操作)也需要900ps,效率很低。

4.3 多周期处理器设计

多周期处理器将指令执行分解为多个周期,每个周期执行一个步骤,功能单元可以在不同指令的不同周期复用。

4.3.1 状态机设计

多周期处理器使用有限状态机(FSM)控制指令执行流程。

状态定义

取指状态(IF)

  • 从指令存储器读取指令
  • PC = PC + 4
  • 下一状态:译码

译码状态(ID)

  • 读取寄存器
  • 符号扩展立即数
  • 下一状态:根据指令类型分支

执行状态(EX)

  • R型:ALU运算
  • Load/Store:计算地址
  • Branch:比较并计算目标地址
  • 下一状态:根据指令类型分支

访存状态(MEM)

  • Load:读取数据
  • Store:写入数据
  • 下一状态:写回

写回状态(WB)

  • R型/Load:写寄存器
  • 下一状态:取指

4.3.2 多周期处理器的优缺点

优点

  • 功能单元可以复用
  • 时钟周期由最慢步骤决定,而不是最慢指令
  • 比单周期处理器效率高

缺点

  • 每条指令需要多个周期
  • 控制逻辑复杂
  • 性能仍然有限

性能比较

  • 单周期:每条指令1个周期,周期900ps
  • 多周期:每条指令3-5个周期,周期300ps
  • 多周期更快,因为周期更短

4.4 流水线处理器设计

流水线处理器将指令执行分解为多个阶段,每条指令占据一个阶段,多条指令同时执行。

4.4.1 五级流水线实现

流水线数据通路

  • 在每个阶段之间插入流水线寄存器
  • IF/ID、ID/EX、EX/MEM、MEM/WB

控制信号传递

  • 控制信号也需要在流水线中传递
  • 每个阶段使用对应的控制信号

PC和指令传递

  • PC值在IF阶段更新
  • 指令在各阶段之间传递

4.4.2 冒险处理

结构冒险处理

  • 分离指令存储器和数据存储器
  • 使用Harvard架构

数据冒险处理

检测逻辑

// 检测EX阶段的数据冒险
if (EX/MEM.RegWrite && EX/MEM.RegisterRd != 0 &&
    (EX/MEM.RegisterRd == ID/EX.RegisterRs ||
     EX/MEM.RegisterRd == ID/EX.RegisterRt))
    stall = 1;

// 检测MEM阶段的数据冒险
if (MEM/WB.RegWrite && MEM/WB.RegisterRd != 0 &&
    (MEM/WB.RegisterRd == ID/EX.RegisterRs ||
     MEM/WB.RegisterRd == ID/EX.RegisterRt))
    stall = 1;

前推逻辑

// 从EX/MEM前推
if (EX/MEM.RegWrite && EX/MEM.RegisterRd != 0 &&
    EX/MEM.RegisterRd == ID/EX.RegisterRs)
    ALUSrcA = EX/MEM.ALUResult;

// 从MEM/WB前推
if (MEM/WB.RegWrite && MEM/WB.RegisterRd != 0 &&
    MEM/WB.RegisterRd == ID/EX.RegisterRs)
    ALUSrcA = MEM/WB.WriteData;

Load-use冒险

  • Load指令的结果在MEM阶段才可用
  • 需要停顿一个周期
  • 检测逻辑:
if (ID/EX.MemRead &&
    (ID/EX.RegisterRd == IF/ID.RegisterRs ||
     ID/EX.RegisterRd == IF/ID.RegisterRt))
    stall = 1;

控制冒险处理

静态预测

  • 预测不跳转:继续取下一条
  • 预测跳转:取跳转目标

动态预测

  • 使用分支历史表
  • 2位饱和计数器
  • 预测准确率可达90%以上

分支延迟槽

  • 分支指令后的指令总是执行
  • 编译器填充有用指令
  • MIPS架构使用

4.4.3 异常处理

异常检测

  • 每个阶段都可能产生异常
  • 需要记录异常类型和位置

异常处理流程

  • 检测到异常时,清空流水线
  • 保存PC到异常处理器
  • 跳转到异常处理程序

精确异常

  • 保证异常前的指令都已完成
  • 异常后的指令都未开始
  • 需要额外的硬件支持

4.5 超标量处理器

超标量处理器可以在一个时钟周期内发射和执行多条指令。

4.5.1 超标量基本概念

发射宽度

  • 每个周期发射的指令数
  • 如2发射、4发射、8发射

功能单元配置

  • 多个ALU
  • 多个load/store单元
  • 多个浮点单元

指令窗口

  • 指令缓冲器
  • 存储待发射的指令
  • 通常32-128条指令

4.5.2 动态调度

动态调度在运行时确定指令执行顺序,最大化指令级并行。

Tomasulo算法

保留站(Reservation Station)

  • 缓冲等待执行的指令
  • 记录操作数可用性
  • 操作数就绪时执行

CDB(Common Data Bus)

  • 广播执行结果
  • 所有保留站监听CDB
  • 收到需要的结果时标记操作数就绪

寄存器重命名

  • 消除WAR和WAW冒险
  • 架构寄存器映射到物理寄存器
  • 使用重命名表跟踪映射

执行流程

发射:从指令窗口取出指令,分配到保留站

执行:操作数就绪时,从保留站发射到功能单元

写结果:执行完成后,结果通过CDB广播

4.5.3 乱序执行与顺序提交

乱序执行

  • 指令按数据可用性执行
  • 提高指令级并行
  • 可能产生异常顺序问题

顺序提交

  • 按程序顺序提交指令
  • 保证精确异常
  • 使用重排序缓冲区(ROB)

重排序缓冲区(ROB)

  • 跟踪指令执行状态
  • 按程序顺序提交
  • 支持分支预测失败恢复

提交流程

  • ROB头部指令完成时提交
  • 更新架构寄存器
  • 释放物理寄存器

4.5.4 分支预测与恢复

分支预测

  • 动态分支预测器
  • 预测准确率90%以上
  • 分支目标缓冲(BTB)

预测失败恢复

  • 检测到预测失败时清空流水线
  • 从ROB恢复正确状态
  • 从正确地址重新取指

恢复机制

  • 保存检查点
  • 回滚到分支点
  • 重新执行

4.6 现代处理器优化技术

4.6.1 多发射与宽发射

多发射技术

  • 静态多发射:VLIW
  • 动态多发射:超标量

宽发射挑战

  • 指令级并行有限
  • 功耗和面积增加
  • 验证复杂度增加

实际配置

  • Intel Core:4-6发射
  • AMD Zen:6发射
  • Apple M1:8发射

4.6.2 非阻塞缓存

非阻塞缓存允许在缓存未命中时继续处理其他请求。

Miss Status Holding Registers(MSHR)

  • 记录未完成的缓存未命中
  • 支持多个未命中同时处理

优点

  • 隐藏内存延迟
  • 提高缓存利用率
  • 支持投机执行

4.6.3 硬件预取

硬件预取根据访问模式提前加载数据到缓存。

预取策略

流预取

  • 检测顺序访问模式
  • 预取下一个缓存行

_stride预取

  • 检测固定步长访问
  • 预取下一个stride

关联预取

  • 学习地址关联
  • 预取相关数据

预取挑战

  • 预取准确率
  • 缓存污染
  • 带宽消耗

4.6.4 同步多线程(SMT)

SMT允许多个线程同时发射和执行。

资源共享

  • 功能单元共享
  • 缓存共享
  • 带宽共享

资源分配

  • 静态分配
  • 动态分配
  • 基于优先级

优点

  • 提高资源利用率
  • 增加吞吐量
  • 隐藏延迟

4.6.5 异构多核

异构多核集成不同类型的核心。

典型配置

  • 大核(Performance Core):高性能、高功耗
  • 小核(Efficiency Core):低功耗、低性能

工作负载分配

  • 前台任务:大核
  • 后台任务:小核
  • 动态迁移

实例

  • ARM big.LITTLE
  • Intel Hybrid(Alder Lake)
  • Apple M1/M2

4.7 处理器功耗管理

4.7.1 功耗来源

动态功耗

  • P_dynamic = α × C × V² × f
  • α:开关活动因子
  • C:负载电容
  • V:供电电压
  • f:时钟频率

静态功耗

  • P_static = I_leakage × V
  • I_leakage:漏电流
  • 随工艺尺寸缩小而增加

4.7.2 功耗管理技术

动态电压频率调节(DVFS)

  • 根据负载调整电压和频率
  • 功耗与电压平方成正比
  • 降低电压可以显著降低功耗

时钟门控(Clock Gating)

  • 关闭不活跃模块的时钟
  • 减少动态功耗
  • 广泛使用

电源门控(Power Gating)

  • 关闭不活跃模块的电源
  • 减少静态功耗
  • 需要保持状态

功耗状态

  • C0:活跃
  • C1: Halt(停止执行,保持状态)
  • C2:Stop-Grant(停止时钟)
  • C3:Sleep(关闭大部分电路)
  • C4:Deep Sleep(更低功耗)
  • C5:Deepest Sleep(最低功耗)

4.7.3 热管理

热设计功耗(TDP)

  • 处理器最大持续功耗
  • 散热系统设计依据

温度监控

  • 片上温度传感器
  • 实时监控温度分布

热节流(Thermal Throttling)

  • 温度过高时降低频率
  • 保护硬件
  • 影响性能

重要知识点

知识点1:数据通路延迟计算

数据通路延迟决定时钟周期:

关键路径

  • 取指:指令存储器访问
  • 译码:寄存器文件读取
  • 执行:ALU计算
  • 访存:数据存储器访问
  • 写回:寄存器文件写入

最慢路径决定周期

  • 单周期:所有阶段之和
  • 流水线:最慢阶段

知识点2:控制信号生成

控制信号根据指令操作码生成:

主解码器

  • 解析操作码
  • 生成基本控制信号

ALU控制

  • 根据ALUOp和funct字段
  • 生成ALU操作信号

示例

// R型指令
RegDst = 1
ALUSrc = 0
MemtoReg = 0
RegWrite = 1
MemRead = 0
MemWrite = 0
Branch = 0
ALUOp = 10

知识点3:流水线性能公式

CPI计算

CPI_流水线 = CPI_理想 + 停顿周期/指令

停顿来源

  • 数据冒险
  • 控制冒险
  • 结构冒险

性能提升

加速比 = CPI_非流水线 / CPI_流水线

知识点4:超标量发射限制

发射宽度限制

  • 指令级并行度
  • 功能单元数量
  • 发射逻辑复杂度

实际限制

  • 数据依赖
  • 控制依赖
  • 内存延迟

知识点5:功耗计算公式

动态功耗

P = α × C × V² × f

节能方法

  • 降低电压(效果最显著)
  • 降低频率
  • 减少开关活动
  • 减少电容

常见误区

误区1:时钟频率越高性能越好

频率只是性能的一个因素。

实际情况

  • IPC(每周期指令数)同样重要
  • 缓存大小和效率
  • 分支预测准确率
  • 内存带宽

性能公式

性能 = 频率 × IPC

误区2:核心数越多性能越好

多核性能取决于应用并行度。

限制因素

  • Amdahl定律
  • 同步开销
  • 内存带宽
  • 功耗限制

误区3:更大的指令窗口总是更好

大指令窗口增加性能,但也增加复杂度。

权衡

  • 面积和功耗
  • 验证复杂度
  • 收益递减

误区4:乱序执行总是值得

乱序执行增加性能,但成本高昂。

适用场景

  • 高性能处理器:值得
  • 低功耗嵌入式:不值得

误区5:处理器设计 once and for all

处理器设计需要持续演进。

演进原因

  • 工艺进步
  • 应用需求变化
  • 安全威胁
  • 功耗限制

实践应用

应用1:处理器性能评估

评估处理器性能需要综合考虑多个指标。

基准测试

  • SPEC CPU:通用计算性能
  • SPECint:整数性能
  • SPECfp:浮点性能

实际工作负载

  • 数据库查询
  • Web服务
  • 视频编码

指标

  • 吞吐量
  • 延迟
  • 功耗效率

应用2:处理器选型

根据应用需求选择合适的处理器。

高性能计算

  • 高核心数
  • 高内存带宽
  • 向量化支持

嵌入式系统

  • 低功耗
  • 小面积
  • 实时性

移动设备

  • 能效比
  • 异构多核
  • 集成GPU

应用3:处理器验证

处理器验证确保设计正确性。

验证方法

  • 功能验证:确保功能正确
  • 性能验证:确保性能达标
  • 功耗验证:确保功耗在预算内

验证工具

  • 仿真器
  • 形式验证
  • 硬件仿真器

应用4:处理器安全

现代处理器需要应对各种安全威胁。

侧信道攻击

  • Spectre
  • Meltdown
  • 缓存攻击

防护机制

  • 缓存分区
  • 内存隔离
  • 执行隔离

安全扩展

  • Intel SGX
  • ARM TrustZone
  • AMD SEV

本章小结

本章深入探讨了处理器设计的关键技术,主要内容包括:

处理器设计基础:介绍了处理器设计的核心目标(性能、功耗、面积、可编程性)和设计方法学。处理器设计需要在多个相互冲突的目标之间进行权衡。

单周期处理器:最简单的处理器实现,每条指令在一个周期内完成。设计简单但性能低下,时钟周期由最慢指令决定。

多周期处理器:将指令执行分解为多个周期,功能单元可以复用。比单周期处理器效率高,但控制逻辑复杂。

流水线处理器:将指令执行分解为多个阶段,多条指令同时执行。通过数据前推、分支预测等技术解决冒险问题,显著提高性能。

超标量处理器:每个周期发射和执行多条指令。使用动态调度(Tomasulo算法)、寄存器重命名、乱序执行等技术最大化指令级并行。

现代处理器优化:包括非阻塞缓存、硬件预取、同步多线程、异构多核等技术。这些技术进一步提高处理器性能和效率。

功耗管理:介绍了动态功耗和静态功耗的来源,以及DVFS、时钟门控、电源门控等功耗管理技术。功耗管理是现代处理器设计的重要考虑。

处理器设计是计算机体系结构的核心内容。从简单的单周期处理器到复杂的现代超标量乱序执行处理器,处理器设计技术不断发展。未来的处理器将面临功耗墙、内存墙、ILP墙等挑战,需要新的架构创新来继续提升性能。

下一章将讨论存储层次结构,这是解决处理器与内存速度差距的关键技术。