目录

    • 一.结构冒险
      • (1)定义:
      • (2)举例
        • 【1】存储器发生结构冒险(存、取冲突)
        • 【2】寄存器发生结构冒险(读、写冲突)
    • 二.数据冒险
      • (1)定义
      • (2)举例
      • 三条前推路径
      • 三种典型的数据依赖关系
    • 三.控制冒险
      • (1)定义
      • (2)举例


前言: 在流水线中会有一种情况,在下一个时钟周期中下一条指令不能执行,这种情况被叫做流水线冒险。流水线冒险一共分为三种情况,分别是结构冒险(Structural hazards)数据冒险(Data hazards)控制冒险(Control hazards)


一.结构冒险

(1)定义:

缺乏硬件支持而导致指令不能在预定的时钟周期内执行的情况。即硬件不支持多条指令在同一时钟周期执行。

(2)举例

【1】存储器发生结构冒险(存、取冲突)

该操作需要对存储器进行存数据与取指令操作。如图所示,按流水线执行时,第一个周期需要存数据的时候,第四个周期需要进行取指令操作,如果将数据与指令放在同一个存储器中那么就会发生结构冒险。

解决方法一

所以我们有不同的存储器进行操作,分为指令存储器和数据存储器。

解决方法二

让流水线发生停顿,即产生空泡(Bubble或Stall)

【2】寄存器发生结构冒险(读、写冲突)

如图所示,读寄存器和写寄存器同时发生,产生结构冒险。

解决方法一(读、写分离)

如果寄存器读写较快的话,我们可以让前半个时钟周期进行写操作,后半个时钟周期进行读操作。然后在寄存器上分别设置单独的读写接口来实现。

解决方法二

同上,产生空泡,使读写错开进行。


二.数据冒险

(1)定义

无法提供指令所需数据而导致指令不能在预定的时钟周期内执行的情况。即一条指令的执行需要等待另一条指令执行完成后所产生的数据。

(2)举例

如下图所示,第二条需要用到第一条指令的数据结果,而如图当调用时使用的是未更新的数据,那么会产生数据冒险。

解决方案一

向其间插入两个周期的空泡(Bubbles)

解决方法二

前推(Forwarding):也叫旁路,是从内部寄存器而非程序员可见的寄存器或存储器中提前取出数据。(前推是根据顺序所起的名字,旁路是根据结构所起的名字。)

因为ALU计算后便可以得到$t0的结果,所以我们可以从这个时候直接将数据取出。

在这里我们需要修改数据通路,另为连接一条通路将结果返回,注意此时要加一个多路选择器。

三条前推路径

∙ \bullet 在EX阶段结尾可以取出ALU的运算结果,无需写回;

∙ \bullet 在MEM阶段结尾可以取出ALU的运算结果,无需写回;

∙ \bullet 在MEM阶段结尾可以取出memory的结果,无需写回;

三种典型的数据依赖关系

∙ \bullet Flow dependence(read after write):简写为RAW,即写后读;寄存器先执行写操作后执行读操作,但是此时还未写回,产生RAW数据冲突。

∙ \bullet Output dependence(write after write):简写为WAW,即写后写;寄存器先执行写操作后又执行写操作,但是此时还未写回,产生WAW数据冲突。

∙ \bullet Anti dependence(write after read):简写为WAR,即读后写;寄存器先执行读操作后执行写操作,但是此时还未读取,产生WAR数据冲突。

E x a m p l e : {\color{Violet}Example:} Example:


三.控制冒险

(1)定义

也叫分支冒险,决策依赖于一条指令的结果,而其他指令正在执行中。比如说分支跳转指令,必须等ALU给出结果后才知道该跳转到哪一条语句。

(2)举例

无法通过旁路的方式传递数据。

无条件直接转移:j Target //流水线无停顿
无条件间接转移: jr rs //流水线停顿一个周期
条件转移: beq rs,rt,immi16 //流水线停顿一个周期

需 要 通 过 动 态 分 支 预 测 指 令 进 行 解 决 。 {\color{Red}需要通过动态分支预测指令进行解决。}

更多推荐

流水线冒险(Pipeline Hazards)|计算机组成