计算机组成原理关于指令流水线数据冒险解决方案的困惑以及梳理

笔者是在做这道题的时候产生的困惑以及解决

image-20251128160311034

附上答案

image-20251128160407884

1.阻塞方式

把I3指令的ID阶段阻塞到时钟6去执行。因为ID阶段是读寄存器的,必须要在I2的WB阶段结束之后,也就是时钟6,一共阻塞3个时钟

2.数据通路方式解决这个问题

我的困惑:

假如A与B指令有数据冲突,数据通路的方式解决的话,那是不是只要在A执行阶段我把结果算出来之后,存到A指令执行阶段的锁存器,然后B指令的执行阶段就可以拿走直接用?还是说B指令的译码阶段取操作数这个操作要等到A指令的EX阶段执行完以后,然后数据通路把A指令的EX段锁存器的内容给到B指令,B指令才去进行EX阶段?

答案在A指令的执行(EX)阶段结束后,结果被存入EX/MEM流水线锁存器。随后,在B指令的EX阶段开始时,转发逻辑可以直接从这个锁存器中取出数据供B指令使用。

简单来说就是:B指令的译码解决还是会拿到错误的值,但是数据通路会在B指令进去EX阶段之前把错误的值用正确的值给覆盖掉。而其实ID阶段拿到错误的值也没事,毕竟也没执行。

转发机制(Data Forwarding)的正确流程

  1. 时序点:
    • A指令的EX阶段结束: 此时,ALU已经计算出了结果。这个结果在时钟周期的末尾被写入到EX/MEM流水线锁存器中。
    • B指令的EX阶段开始: 在下一个时钟周期开始时,B指令进入EX阶段。B指令需要从寄存器读取的操作数(例如A指令产生的结果)已经准备就绪。
  2. 转发如何连接:
    • 硬件上,会有一条路径从A指令的EX/MEM锁存器的输出端,直接连接到B指令的EX阶段的ALU输入端的多路选择器(MUX)
    • 当检测到数据冲突(即B指令需要的源寄存器正是A指令要写入的目标寄存器)时,转发单元会生成控制信号,让这个多路选择器选择从EX/MEM锁存器来的转发数据,而不是选择从ID/EX锁存器来的(可能已过时的)寄存器文件数据。
  3. B指令的译码(ID)阶段不受影响:
    • B指令的ID阶段会照常进行,它会从寄存器文件中读取操作数。但是,由于A指令还没有将结果写回寄存器文件(WB阶段),此时读出的值是旧的、不正确的
    • 这个旧值会被传递到ID/EX锁存器中。这没有关系,因为当B指令进入EX阶段时,转发逻辑会“覆盖”掉这个旧值,选择正确的转发值。这才是转发的精髓——它修复的是EX阶段的输入,而不是阻止ID阶段的读取

为什么第二种说法是错的?

第二种说法是:“B指令的译码阶段取操作数这个操作要等到A指令的EX阶段执行完以后…B指令才去进行EX阶段?”

  • 这种描述听起来更像是阻塞(Stalling) 策略,而不是转发策略。
  • 在转发机制下,B指令的ID阶段不需要等待A指令的EX阶段完成。B指令的ID阶段可以紧跟着A指令的ID阶段正常进行,流水线继续保持流动,没有插入气泡(Bubble)。冒险的解决是在数据进入ALU的“最后一刻”通过转发完成的。
  • 如果让B指令的ID阶段等待,那就失去了转发机制“避免流水线停顿”的最大优势。