vault backup: 2026-06-16 21:34:37

This commit is contained in:
2026-06-16 21:34:37 +08:00
parent dcb3efa297
commit ff3343cb29
15 changed files with 2343 additions and 0 deletions
@@ -0,0 +1,135 @@
---
tags:
- 计算机系统结构
- 重点复习
- 指令级并行
- ILP
create time: 2026-06-16 21:21
---
# 小题 5 — 指令级并发的开发方法
## 概述
本题考查**指令级并行**(Instruction-Level Parallelism, ILP)的开发方法,包括**静态方法**(编译器主导)和**动态方法**(硬件主导)两大类。ILP 是提升单处理器性能的核心技术途径。
> [!tip] 考试重点
> 了解有哪些主要的 ILP 开发方法即可,重点区分"静态"和"动态"的分类及代表技术。不需要深入每种方法的实现细节。
## 正文
### 一、什么是指令级并行(ILP)?
**指令级并行**是指程序中多条指令**同时执行或重叠执行**的可能性。ILP 的开发目标是在不改变程序语义的前提下,尽可能让更多的指令在同一时刻处于执行状态。
> [!question] ILP 的理论基础是什么?
> 程序中大部分指令之间**没有**数据依赖或控制依赖。研究表明,一个典型程序中每条指令平均只有 0.5~1.5 条真依赖。这意味着在理论上,一个程序可以同时执行 3~5 条指令——但需要硬件或编译器来发现和利用这种并行性。
### 二、开发方法总览
```mermaid
graph TD
ROOT["ILP Development"] --> S["Static Methods"]
ROOT --> D["Dynamic Methods"]
S --> S1["Loop Unrolling"]
S --> S2["Software Pipelining"]
S --> S3["Trace Scheduling"]
S --> S4["Instruction Scheduling"]
D --> D1["Superscalar"]
D --> D2["Out-of-Order Execution"]
D --> D3["Speculative Execution"]
D --> D4["Register Renaming"]
D --> D5["Branch Prediction"]
D --> D6["Dynamic Scheduling"]
```
### 三、静态方法(编译器主导)
静态方法在**编译时**分析和优化指令顺序,运行时按优化后的顺序执行。
| 方法 | 原理 | 效果 |
|------|------|------|
| **循环展开**(Loop Unrolling) | 将循环体复制多份,减少循环控制指令的开销 | 减少分支指令占比,增加调度空间 |
| **软件流水**(Software Pipelining) | 从不同迭代中抽取指令组成新的循环体 | 使每次迭代中各段重叠执行 |
| **轨迹调度**(Trace Scheduling) | 选择最可能执行的路径(trace),在该路径上全局优化 | 对热路径的优化效果显著 |
| **指令调度**(Instruction Scheduling) | 重排指令顺序以避免数据冲突和结构冲突 | 减少 Stall,提高流水线利用率 |
> [!note] 循环展开示例
>
> **原始代码**(4 次迭代):
> ```
> for (i = 0; i < 4; i++)
> C[i] = A[i] + B[i];
> ```
>
> **循环展开 2 次**:
> ```
> C[0] = A[0] + B[0];
> C[1] = A[1] + B[1]; // 与上一条无依赖,可并行
> C[2] = A[2] + B[2];
> C[3] = A[3] + B[3]; // 与上一条无依赖,可并行
> ```
>
> 展开后分支指令从 4 条减为 0 条(或 1 条),且相邻指令的独立性更高,编译器有更多调度自由度。
> [!question] 静态方法的局限性?
> 1. 编译时无法知道**运行时信息**(如 Cache 是否命中、分支方向),调度可能不是最优的
> 2. 不同的输入数据可能改变最优的指令顺序
> 3. 编译器必须保守处理——如果不确定两条指令是否相关,就假定相关,不做并行化
### 四、动态方法(硬件主导)
动态方法在**运行时**由处理器硬件发现和利用 ILP。
| 方法 | 原理 | 效果 |
|------|------|------|
| **超标量**(Superscalar) | 每个时钟周期发射**多条指令**到多个功能部件 | 基础并行执行能力 |
| **乱序执行**(Out-of-Order Execution) | 指令不按程序顺序执行,就绪即可执行 | 消除等待,提高利用率 |
| **推测执行**(Speculative Execution) | 在分支结果确定前就执行分支目标处的指令 | 隐藏分支延迟 |
| **寄存器重命名**(Register Renaming) | 将逻辑寄存器映射到物理寄存器,消除名相关 | 消除 WAR 和 WAW 冲突 |
| **分支预测**(Branch Prediction) | 预测分支方向,提前取指和执行 | 减少控制冲突 |
| **动态调度**(Dynamic Scheduling) | 如 Tomasulo 算法,硬件动态分配资源和调度指令 | 处理数据相关的等待 |
```mermaid
graph LR
subgraph InOrder["In-Order Issue"]
I1["Instruction 1"] --> I2["Instruction 2"] --> I3["Instruction 3"]
end
subgraph OutOfOrder["Out-of-Order Execution"]
O1["Instruction 1"] --> O_EX1["Execute"]
O2["Instruction 2"] -->|"Stall (waiting)"| O2_W["Wait"]
O3["Instruction 3"] -->|"Ready first"| O_EX3["Execute"]
end
```
> [!note] Tomasulo 算法简介
> Tomasulo 算法是 IBM 在 1967 年为 System/360/91 开发的动态调度算法,核心思想:
> 1. **保留站**(Reservation Station):每个功能部件有若干保留站,存放等待执行的指令及其操作数
> 2. **公共数据总线**(CDB):运算结果通过 CDB 广播,所有等待该结果的保留站同时获取
> 3. **寄存器重命名**:通过保留站标签替代寄存器号,自动消除 WAR 和 WAW 冲突
>
> Tomasulo 算法是现代超标量处理器乱序执行引擎的理论基础。
### 五、静态 vs 动态方法对比
| 对比维度 | 静态方法 | 动态方法 |
|----------|----------|----------|
| 决策时机 | 编译时 | 运行时 |
| 信息来源 | 程序结构分析 | 实际运行状态 |
| 适应性 | 差(无法适应运行时变化) | 好(根据实际情况调整) |
| 硬件开销 | 低 | 高 |
| 典型代表 | 循环展开、指令调度 | 超标量、乱序执行 |
| 适用场景 | 嵌入式、低功耗处理器 | 高性能通用处理器 |
> [!question] 现代处理器如何组合使用?
> 现代处理器(如 Intel Core、ARM Cortex-A)**同时使用**静态和动态方法:
> - 编译器做指令调度和循环展开(静态)
> - 硬件做超标量发射、乱序执行和分支预测(动态)
> - 两者互补:编译器提供良好的初始顺序,硬件进一步挖掘运行时并行性
## 关联笔记
- [[计算机系统结构/复习文档/流水线技术]]
- [[小题3-控制冲突的解决措施]]
- [[小题2-流水线的分类]]