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

6.1 KiB
Raw Permalink Blame History

tags, create time
tags create time
计算机系统结构
重点复习
指令级并行
ILP
2026-06-16 21:21

小题 5 — 指令级并发的开发方法

概述

本题考查指令级并行(Instruction-Level Parallelism, ILP)的开发方法,包括静态方法(编译器主导)和动态方法(硬件主导)两大类。ILP 是提升单处理器性能的核心技术途径。

[!tip] 考试重点 了解有哪些主要的 ILP 开发方法即可,重点区分"静态"和"动态"的分类及代表技术。不需要深入每种方法的实现细节。

正文

一、什么是指令级并行(ILP)?

指令级并行是指程序中多条指令同时执行或重叠执行的可能性。ILP 的开发目标是在不改变程序语义的前提下,尽可能让更多的指令在同一时刻处于执行状态。

[!question] ILP 的理论基础是什么? 程序中大部分指令之间没有数据依赖或控制依赖。研究表明,一个典型程序中每条指令平均只有 0.51.5 条真依赖。这意味着在理论上,一个程序可以同时执行 35 条指令——但需要硬件或编译器来发现和利用这种并行性。

二、开发方法总览

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 算法,硬件动态分配资源和调度指令 处理数据相关的等待
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)同时使用静态和动态方法:

  • 编译器做指令调度和循环展开(静态)
  • 硬件做超标量发射、乱序执行和分支预测(动态)
  • 两者互补:编译器提供良好的初始顺序,硬件进一步挖掘运行时并行性

关联笔记