Files
final-exam/计算机系统结构/重点复习/小题5-指令级并发的开发方法.md
T

136 lines
6.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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-流水线的分类]]