计算机体系结构的总复习
课内使用的是《Computer Organization and Design: The Hardware/Software Interface, 6th Edition》一书。
参考资料:
Introduction
什么是计算机体系结构?
根据目标机器的特定需求,在成本、功耗、可用性等约束下最大化机器性能。包括 ISA、计算机组织(微体系结构)和硬件实现。
关键设计思想
- 抽象(Abstraction)
- 分层设计:应用层 → 编译器 → OS → ISA → 硬件电路
- 关键价值:简化复杂系统设计(如指令集抽象)
摩尔定律(Moore’s Law)
- 原始表述(1965):晶体管密度每1-2年翻倍
- 现代挑战:
- 3D堆叠(如Cerebras晶圆级芯片,1.2万亿晶体管)
- Chiplet技术(AMD GPU应用,解决良率问题)
- 功耗墙:因芯片功耗密度过高导致的物理限制
局部性原理与存储层次
- 存储金字塔:寄存器 → L1/L2/L3缓存 → 主存 → 虚拟存储 → 磁盘
冗余容错(Dependability via Redundancy)
- 案例:ECC内存(9芯片 vs 非ECC的8芯片,冗余芯片纠错)
并行化(Parallelism)
- 层级:
- 指令级(ILP):流水线、乱序执行
- 数据级(DLP):SIMD/向量处理器
- 任务级(TLP):多线程/多核
- 层级:
Representation and Computation of Data
冯诺依曼架构和哈佛架构
- 冯诺依曼架构:存储程序,数据和指令共享同一存储器
- 哈佛架构:数据和指令分开存储,通常用于嵌入式系统
原码反码补码
- 原码:符号位+绝对值
- 反码(1-补码):符号位不变,负数取反
- 补码(2-补码):符号位不变,负数取反后加1
- unsigned extension:高位补0
- signed extension:高位补符号位
- 数据类型转换:int和unsigned运算转为unsigned
Ripple-Carry Adder
- 全加器:输入A、B、Cin,输出Sum和Cout
- Ripple-Carry Adder:多个全加器串联,计算A+B+C的和
- 延迟:每个全加器的延迟为1,n个全加器总延迟为n
- 溢出检测:对于n位补码加法器,若A和B符号位相同且与Sum符号位不同,则发生溢出
IEEE 754 浮点数
- 单精度:1位符号位,8位指数,23位尾数
- 双精度:1位符号位,11位指数,52位尾数
规格化:尾数的最高位为1,指数偏移量为127(单精度)或1023(双精度)公式
- 公式:
非规格化:指数为0,尾数不以1开头
- 公式:
- 大端/小端序
- 大端序:高位字节在前
- 小端序:低位字节在前
Single Precision | Double Precision | Object Represented | ||
---|---|---|---|---|
E (8) | F (23) | E (11) | F (52) | |
0 | 0 | 0 | 0 | true zero (0) |
0 | nonzero | 0 | nonzero | |
anything | anything | |||
0 | 0 | |||
255 | nonzero | 2047 | nonzero | not a number (NaN) |
浮点数加法
- 步骤:
- 对阶:调整指数,使两个数的尾数对齐(一般小阶数向大阶数对齐)
- 相加尾数:将对齐后的尾数相加
- 规格化结果:如果尾数溢出,调整指数并规格化
- 舍入:根据舍入规则处理最后的结果
- 举例:
- 2.6125 × 101 = 26.125 = 11010.001 = 1.1010001000 × 2^4
- 4.150390625 × 10−1 = .4150390625 = .0110101001 = 1.10101001 × 2^−2 = 0.0000011010101 × 2^4 (对阶,小阶往大阶对,小数点左移六位)
- 1.1010001000
+.0000011010101
− − − − − − − − − − − − − − − − − − −−
1.1010100010101 (尾数相加、规格化、舍入)
= 1.1010100011 × 2^4 (检查,无溢出)
= 11010.100011 × 2^0 = 26.546875 = 2.6546875 × 10^1
浮点误差
- 十进制数值位多于 7 位,浮点数表示的是近似值
- 不满足结合律
RISC-V
RISC & CSIC
Parameter | RISC | CISC |
---|---|---|
Instruction Types | Simple | Complex |
# of Instructions | Reduced (30-40) | Extended (100-200) |
Duration of an Instruction | One Cycle | More Cycles (4-120) |
Instruction Format | Fixed | Variable |
Instruction Execution | ”In Parallel (Pipeline)” | ”Sequential” |
Addressing Modes | Simple | Complex |
Instruction Accessing the Memory | Two: Load and Store | Almost all from set |
Register Set | Multiple | Unique |
Design Complexity | In compiler | In CPU |
5-stage Pipeline
- 阶段:
- IF(Instruction Fetch):从指令存储器获取指令
- ID(Instruction Decode):解码指令,读取寄存器
- EX(Execute):执行算术逻辑运算或计算地址
- MEM(Memory Access):访问数据存储器
- WB(Write Back):将结果写回寄存器
- 流水线瓶颈: 受最长延时的阶段限制(决定时钟周期)
RV32I vs RV64I
- 指令长度均为32 bits
- 寄存器宽度和地址空间为32/64 bits
- 标准扩展
- M(乘除法)
- A(原子操作)
- F(单精度浮点)
- D(双精度浮点)
- V (向量处理)
RISC-V 指令
大立即数加载
lui rd, imm
:将 20 位立即数左移 12 位存入 rdauipc rd, imm
:PC + (imm << 12) 存入 rd(用于长跳转)
条件分支
beq | bne | blt | bge | bltu(unsigned) | bgeu(unsigned) |
---|---|---|---|---|---|
= | != | < | >= | < | >= |
移位操作
- 左移:
sll
/slli
(逻辑=算术) - 右移:
srl
(逻辑),sra
(算术补符号位)
- 左移:
符号扩展策略
lb
:字节加载后符号扩展lbu
:字节加载后零扩展
跳转
jal rd, offset
:跳转到 offset 处,rd 存储返回地址 PC+4jalr rd, rs1, offset
:跳转到 rs1 + offset 处,rd 存储返回地址 PC+4- jal跳转距离有限,jalr可以跳转到任意地址,实现函数返回机制
RSIC-V Conventions
ret: jalr x0, x1, 0
(跳转到x1地址)
- 发生函数调用前,保存所有 caller 使用的 caller-save 的寄存器,function call 结束后恢复
- 函数调用时,当使用 callee-save 的寄存器时,先保存寄存器,后恢复
Processor
Need registers between stages to hold information produced in previous cycle
Hazard
- 结构冒险
- 资源冲突(e.g., 单端口存储器冲突)→ 分离指令/数据Cache
- 数据冒险
- 前递(Forwarding):EX/MEM或MEM/WB结果直通ALU输入(EX部分)
- 条件:
EX/MEM.RegisterRd == ID/EX.RegisterRs
- 条件:
- Load-Use冒险:必须插入1周期气泡(无法用前递解决,load在写回后才可使用)
- 前递(Forwarding):EX/MEM或MEM/WB结果直通ALU输入(EX部分)
- 控制冒险
- 分支预测:静态(默认不跳转)vs 动态(2位预测器+BTB)
- 早判分支:ID阶段计算目标地址和条件 → 减少气泡
指令重排:解决Load-Use冒险,避免气泡
控制信号
处理器关键控制信号精要表
控制信号 | 作用 | 取值 | 对数据流的影响 | 典型应用场景 | |
---|---|---|---|---|---|
ALUSrc | ALU操作数2来源选择 | 0 =寄存器文件1 =立即数 | 决定ALU计算使用寄存器值还是立即数 | addi x1, x2, 100 (立即数加法) | |
MemtoReg | 写回寄存器数据来源选择 | 0 =ALU结果1 =内存数据 | 控制写回数据是计算结果还是内存加载值 | ld x1, 0(x2) (加载指令) | |
PCSrc | 下条指令地址来源选择 | 0 =PC+41 =分支目标地址 | 决定顺序执行或跳转到分支目标 | beq x1, x2, label (条件分支) | |
RegWrite | 寄存器写使能 | 0 =禁止写1 =允许写 | 控制计算结果是否写入寄存器文件 | 所有写寄存器指令 | |
ForwardA | ALU操作数1前递选择 | 00 =寄存器文件10 =EX/MEM结果01 =MEM/WB结果 | 解决EX阶段数据冒险,提供最新操作数 | add x1,x2,x3 sub x4,x1,x5 | |
PCWrite | 程序计数器更新控制 | 0 =冻结PC1 =更新PC | 发生load-use冒险时暂停取指 | ld x1,0(x2) 后接add x3,x1,x4 | |
MemRead | 数据存储器读使能 | 0 =禁止读1 =允许读 | 控制是否读取内存数据 | 所有加载指令 | |
MemWrite | 数据存储器写使能 | 0 =禁止写1 =允许写 | 控制是否写入内存数据 | 所有存储指令 |
冒险解决链
MemRead
→ 检测load-use冒险 →PCWrite=0
冻结流水 →Forward
提供数据 →RegWrite
写回分支控制流
PCSrc=1
时覆盖PC默认更新路径 → 需冲刷错误路径指令(清空IF/ID寄存器)数据前递
ForwardA
:ALU操作数1前递选择ForwardB
:ALU操作数2前递选择
Branch Prediction
静态分支预测
- 默认不跳转:假设分支不成立
- 基于目标地址:假设分支总是跳转到固定地址
动态分支预测
- 两位饱和计数器:使用2位状态机预测分支
00
:强不跳转01
:弱不跳转10
:弱跳转11
:强跳转
- 分支目标缓冲器(BTB):存储分支指令的目标地址
- 分支历史表:记录最近分支的执行结果,更新预测状态
错误处理
- 分支预测错误:EX阶段检测
- 清空IF/ID寄存器:如果预测错误,清空指令获取和解码阶段的寄存器
- 更新PC:将PC设置为正确的目标地址
- 重新获取指令:从正确的地址重新获取指令
处理器性能
- CPI(Cycles Per Instruction):每条指令平均需要的时钟周期数 = 基础CPI(理想为1) + 冒险气泡数(数据冒险、分支预测错误)
Memory Hierarchy
磁盘访问时间
- 磁盘访问时间 = 寻道时间 + 旋转延迟 + 传输时间
- 旋转延时 = 平均旋转延迟 = 1/2 * (rpm / 60)
缓存(Cache)
直接映射缓存 (Direct Mapped Cache)
- 唯一映射规则:内存块地址
mod
缓存块数 → 确定唯一缓存位置
公式:缓存索引 = (块地址) % (缓存块数量)
- 地址结构:
1
| 高位 Tag 位 | 中位 Index 位 | 低位 Offset 位 |
- 访问流程:
- 用
Index
定位缓存行 - 检查
Valid
位 - 比较
Tag
位 - 若匹配且有效 → 命中,用
Offset
读取数据
- 用
组相联缓存 (Set Associative Cache)
- 分组映射:
- 缓存分为 S 个组(Set),每组包含 W 个路(Way)
- 内存块映射到特定组,但可放入组内任意路
公式:组索引 = (块地址) % (组数 S)
- 地址结构:
1
| Tag 位 | Set Index 位 | Offset 位 |
- 访问流程:
- 用
Set Index
定位组 - 并行比较组内W个Tag
- 任一匹配且有效 → 命中
- 用
- 多路组相联
替换策略(组满时)
- LRU (Least Recently Used):
记录访问时间戳,替换最久未使用的块(硬件成本高) - 随机替换:
随机选择一路替换(简单,性能接近LRU)
全相联缓存 (Fully Associative Cache)
- 自由映射:内存块可放入任意缓存位置
- 地址结构:
1
| 高位 Tag 位 | 低位 Offset 位 | // 无Index位
- 访问流程:
- 并行比较所有缓存块的Tag
- 任一匹配且有效 → 命中
替换策略
- LRU:必须实现(否则性能严重下降)
- 硬件代价:
记录所有块的访问顺序,成本极高(如64KB缓存需1024个比较器)
写策略
- 写命中
- 写直达 (Write-Through):同时更新缓存和内存(一致性高,速度慢)。
- 写回 (Write-Back):仅更新缓存,置换时写回内存(标记Dirty位)。
- 写缺失
- 写分配 (Write-Allocate):加载缺失块到缓存再修改。
- 写绕过 (Write-Around):直接写内存,不加载缓存。
虚拟内存 (Virtual Memory)
- 分页 (Paging):虚拟地址 → 物理地址(页大小通常4KB)。
- 页表 (Page Table):
- 存储虚拟页号到物理页帧/磁盘地址的映射。
- 页表项 (PTE) 包含 Valid、Dirty、Reference 位。
- 缺页处理 (Page Fault):
页不在内存时,从磁盘加载(耗时百万周期),由OS处理。
TLB (快表)
- 缓存常用PTE,加速地址转换。
- TLB缺失处理:
- 硬件加载PTE(简单页表)或软件异常处理(复杂页表)。
替换与写策略
- LRU替换:利用Reference位跟踪使用情况。
- 写回策略:Dirty页置换时写回磁盘。
并行处理器
向量处理器(Vector Processors)
- 核心思想:单指令操作向量寄存器(一组数据)。
- 优势:
- 减少指令带宽(1条指令完成N次操作)。
- 连续内存访问模式,优化预取和带宽利用。
- RISC-V Vector Extension (RVV):
- 32个向量寄存器(每寄存器64元素),支持
vadd.vv
(向量加)、fmul.d.vs
(标量乘向量)等指令。
- 32个向量寄存器(每寄存器64元素),支持
- 关键优化:
- 链式执行(Chaining):元素级流水线转发,解决RAW hazard。
- 多通道(Multi-lane):并行处理多个元素,提升吞吐量。
- 掩码执行(Masking):条件执行(如
fcmp.neq.v
+fsub.v
实现条件减法)。
SIMD扩展(如Intel AVX)
- CPU内集成宽寄存器(如512位AVX,支持16个单精度浮点并行计算)。
- 适用场景:密集计算(图像处理、科学计算)。
GPU
核心架构(以NVIDIA Fermi为例)
- Streaming Multiprocessor (SM):
- 32个CUDA核心(每核心支持浮点/整数运算)。
- 16个加载/存储单元 + 4个特殊函数单元(sin/exp等)。
- 32K寄存器文件 + 64KB共享内存/L1缓存。
- SIMT执行模型:
- 线程以32线程的 Warp 为单位调度。
- 硬件多线程切换隐藏内存延迟。
- Streaming Multiprocessor (SM):
CPU vs GPU设计哲学
| 组件 | CPU | GPU |
|————————|————————————|———————————-|
| 核心目标 | 低延迟、复杂控制流 | 高吞吐、数据并行 |
| 缓存 | 大容量多级缓存 | 小缓存,依赖高带宽显存|
| 晶体管分配 | 控制逻辑、分支预测 | 浮点单元、多线程上下文|
| 适用场景 | 串行代码、任务调度 | 并行计算(AI/HPC) |
Domain Specific Architectures
通用架构的低效性(Turing Tariff)
- 问题:通用处理器(CPU/GPU)执行特定任务时效率低下,存在性能与能耗开销。
- 原因:指令获取、解码、分支预测等控制开销消耗大量能量(占90%-99.9%)。
- 数据对比:
- 32位整数加法(28nm工艺):ASIC仅需68fJ,ARM A15 CPU需250pJ(约4000倍能耗)。
- 解决方案:
- 硬件中心:DSA(领域特定架构)针对特定领域优化。
- 软件中心:领域特定语言(DSL)如TensorFlow/PyTorch,显式表达算子结构。
- 混合方法:DSA + DSL组合(如TPU + TensorFlow)。
DSA加速来源
- 四大优化技术:
- 数据专用化
- 定制数据类型(如4位压缩权重),减少内存占用(例:EIE加速器内存占用降30倍)。
- 并行性
- 大规模并行单元(如TPU的脉动阵列),需避免内存瓶颈。
- 本地优化内存
- 小容量SRAM替代DRAM:SRAM读能耗5pJ/bit,DRAM读能耗640pJ/bit(差128倍)。
- 数据压缩提升有效带宽(例:NVDLA权重稀疏化使片上内存容量提升3-10倍)。
- 减少开销
- 消除指令获取/解码、分支预测等控制开销。
- 低精度计算(如8位整型替代32位浮点)。
- 数据专用化
DSA在AI加速中的应用
- 核心算子:矩阵乘法(GEMM)和卷积(Conv)占DNN计算90%以上(如AlexNet)。
- 内存瓶颈优化:
- 数据复用:
- 卷积复用(滑动窗口)、特征图复用(批处理)、滤波器复用。
- 数据复用:
RISC-V生态中的DSA
- 定制流程:
- 扩展指令集:添加RoCC(Rocket Chip协处理器)自定义指令。
- 集成加速器:通过解耦接口(Ready-Valid协议)连接RISC-V核心。
- 开发工具:使用Chipyard平台生成RTL,支持FPGA仿真与ASIC流片。
- RoCC机制:
- 指令格式:继承RISC-V R-type,通过
xd/xs1/xs2
标志控制数据传递。 - 通信接口:
- 命令接口:发送指令+
rs1/rs2
数据至加速器。 - 响应接口:加速器写回结果至
rd
寄存器。
- 命令接口:发送指令+
- 优势:支持DMA直接内存访问,避免缓存一致性瓶颈。
- 指令格式:继承RISC-V R-type,通过
CAAQA选读
计算机的实现包括两个方面:组成和硬件
1.9 计算机设计的量化原理
1.9.1 充分利用并行
- 系统级并行:使用多个处理器/存储设备
- 处理器级并行: 使用多核处理器/指令并行(流水线化、超标量)
- 数字设计级并行:使用多路复用器、加法器等并行电路
1.9.2 局部性原理
程序常常重用最近用过的数据和指令
- 时间局部性
- 空间局部性
1.9.4 Amdahl’s Law
- 计算机系统的性能提升受限于最慢的部分
- 性能提升 =
- p: 被加速的部分
- s: 加速比
1.9.5 处理器性能公式
- CPU时间 = CPU时钟周期数 * 时钟周期时间
- CPI(每条指令时钟周期数) = CPU时钟周期数 / 指令数
- 处理器性能 = 时钟频率 每时钟周期指令数 (CPI) 指令数
2.4 虚拟存储器
将物理存储器分成块,分给不同进程