流水线中的相关和冒险

并行需要解耦依赖,依赖又称相关性。当俩个事件存在相关性而同时执行就有可能产生冒险(Hazard)。程序上下指令间存在天然的依赖性,指令间的依赖性可用数据依赖图表示,而流水线同时执行多条指令必然要面对冒险的问题。

在数字电路中也有冲突冒险的概念,也表示对公共资源的冲突,此文的冒险则侧重于流水线并行中的冒险概念。

相关性

产生冒险一定相关,相关不一定产生冒险。分析相关的粒度到指令级,和流水线的粒度保持一致。

  • 数据相关:数据流间的相关性。“输入A-指令A-输出A”,“输入B-指令B-输出B”,指令B的输入是指令A的输出,二者构成数据相关。依赖关系可以传递,数据相关关系可以构成相关链“指令A-指令B-指令C”…… 这是逻辑上的相关联系。数据相关指令必须按顺序执行。
  • 名称相关:“伪相关”的一种,寄存器名称冲突但数据上不存在冲突,可通过在软件或硬件上实现寄存器重命名消除
  • 控制相关:分支的相关冲突。

流水线粒度

以流水线单元为粒度分析冲突是冒险。

  • 数据流
    • 数据冒险
  • 控制流
    • 分支冒险
  • 硬件资源
    • 结构冒险

数据冒险

数据相关必须按照原本顺序执行,但按照顺序执行不一定代表不会发生冲突。由于流水线并行俩个顺序指令挨着很近发生重叠,仍有可能冲突。指令A先于指令B执行,根据发生冲突的不同位置划分如下:

指令 B \ 指令 A 输入(R) 输出(W)
输入(R) - RAW
输出(W) WAR WAW

比如 RAW 冒险,指令 A 先于指令 B 执行,按理说 B 应该能正确读取到 A 的输出,但是由于 pipeline ,B 读取输入时 A 还没有输出,造成了冒险。对于 RAW,分为俩种情况,B 读取时输入时 A 已经产生了输出数据,只是没有存储到寄存器里,此时可以引入额外的数据旁路解决(数据转发);若 B 读取时 A 还没产生输出,只能插入气泡停顿等待数据生成。

分支冒险

即下一条指令依赖上一条指令的分支结果,一般可以引入分支预测解决。

结构冒险

在 pipeline 不同阶段对某个相同硬件资源访问冲突。

比如经典的五级流水线 IF-ID-EX-MEM-WB,各级对硬件资源的访问需求如下

Stage Requirements
IF 缓存读指令
ID 读寄存器
EX 数据总线
MEM 缓存读写
WB 写寄存器

比如如果 Register File 使用 Signal Port 实现,那么 ID 和 WB 可能会发生冒险,如果存在多发射结构,则 EX 多个执行单元会竞争数据总线等等。

posted @ 2024-07-21 00:39  DevilXXL  阅读(23)  评论(0编辑  收藏  举报