【问题标题】:Example with MIPS, Pipelining and Branch Delay Slot使用 MIPS、流水线和分支延迟槽的示例
【发布时间】:2018-07-16 22:44:00
【问题描述】:

我正在准备考试并且有这样的例子。以下代码:

1: SLL $1, $1, 2
2: LW $2, 1000($1)
3: BEQL $2, $0, END
4: ADDI $3, $2, 1
5: MULT $3, $2
6: MFLO $4
END:
7: J QUIT
...
QUIT:
100: NOP

在RISC处理器(准MIPS指令集)上执行

  • 五阶段管道
  • 绕过
  • 没有动态调度
  • 分支延迟槽
  • 另外我们知道,分支不会被占用

我的任务是了解分支延迟槽在这种情况下如何工作并构建正确的管道图。

我有一个官方的解决方案,它给出了下图,没有任何解释:

1: SLL $1, $1, 2         IDEMW  
2: LW $2, 1000($1)        I---DEMW  
3: BEQL $2, $0, END           I---DEMW  
4: ADDI $3, $2, 1                 IDx
5: MULT $3, $2                       IDEMW
6: MFLO $4                            I---DEMW

据我了解,ADDI 在 Branch Delay Slot 中执行并停止 在处理器了解之后,该分支没有被采取,导致我们得到错误结果的原因。我的问题是

  • 我说的对吗?
  • 如果是,为什么 ADDI 在 Branch Delay Slot 中执行而不是 Jump?

【问题讨论】:

  • 如果分支被采用,那么为什么要停止ADDI?事实上,为什么它会被阻止?无论是否采用分支,延迟槽中的指令都会完全执行。
  • AFAIK 典型的 5 级 MIPS 流水线将寄存器访问分为两个阶段,因此即使没有显式转发,相关指令的 D 阶段也可以与其相关性的 W 发生在同一时钟内。
  • 2Jester 好吧,在我们的约定(可能不是那么真实)中,在分支可能指令的情况下,就像这里一样,BDS 中的指令会因错误的预测而停止。问题是为什么是 ADDI 而不是 J。
  • @EOF 这不完全是 MIPS。在这里,所有指令只有 IF、DE、EX、ME 和 WB 阶段。而且图是官方的解决方案,所以我认为是对的。
  • 看起来像一些高级 MIPS IV 功能(math-atlas.sourceforge.net/devel/assembly/mips-iv.pdf)——事实上,ADDI 被抛弃了(第 45 页)。你是什​​么意思“为什么ADDI而不是跳跃”

标签: assembly mips pipeline risc


【解决方案1】:

CPU 继续按顺序读取指令,即在执行期间(已经获取、解码并且现在正在处理剩余的阶段,我不知道您的确切阶段,所以这只是一般描述)beql 它会让管道的另一部分空闲来获取下一条指令,但分支还没有完成,所以PC 仍然指向分支后的下一条指令 -> 那是“分支延迟槽”。

在经典 MIPS 上,这条下一条指令被获取、解码和执行,同时分支可能会也可能不会将 PC 修改为分支目标,因此每次都会执行分支延迟槽指令。只有在没有发生分支时才会执行它之后的下一条指令,即PC 按顺序在“分支延迟槽”位置之后继续。如果分支确实修改了PC,则获取+解码将注意到并解码来自新目的地的下一条指令,因此在经典 MIPS 上,分支延迟槽只有 1 条指令“大”(我不知道是否更复杂MIPS CPU 可以有更多的阶段和更多的延迟槽可用,技术上具有 5 阶段流水线甚至 5 条指令延迟听起来硬件可能,但实际使用可能非常困难,而且听起来会产生更多的问题而不是帮助)。

BEQL 是更复杂的指令,如果分支条件失败,则在执行中途终止延迟槽指令。

有关BEQL的详细说明,请参阅第45页http://math-atlas.sourceforge.net/devel/assembly/mips-iv.pdf

所以“NullifyCurrentInstruction()”可能就是图中的“x”。图表中的其余内容,我只是猜测,因为我没有研究您的 5 阶段细节,但是在获取和解码后的第二个 LW(?)发现它依赖于 $1,所以它在依赖阶段等待上一条指令W 阶段。等等...ADDI 不依赖任何东西,所以它几乎与BEQL 并行执行,并在最后被杀死。

但我不明白为什么每次“I”阶段被释放时都没有“I”阶段,看起来“I”在等待某些东西,最后你最多有 2 个指令在同一时间。

无论如何,如果不研究您问题中使用的 CPU 的技术细节,这是非常难以理解的,我不想研究它,我什至不确定您拥有什么样的 CPU,以及从哪里获得它技术文档。


编辑:我也会在这里尝试提取 pdf 的相关部分,以使这个答案不仅仅是“链接”,而是复制 pdf 可能会很棘手......

BEQL MIPS IV CPU 的指令文档:

说明: 如果 (rs = rt) 那么分支_可能
在分支延迟槽中,将一个 18 位带符号偏移(16 位偏移字段左移 2 位)添加到分支之后的指令地址(不是分支本身),以形成 PC 相对的有效目标地址。
如果GPRrs和GPRrt的内容相等,则在延迟槽中的指令执行完后跳转到目标地址。如果不采取分支,则不执行延迟槽中的指令。

操作:
我:
tgt_offset ← sign_extend(offset || 02)
条件 ← (GPR[rs] = GPR[rt])
我+1:
如果条件那么
PC ← PC + tgt_offset
其他
NullifyCurrentInstruction()
结束

【讨论】:

  • 啊,不知道“可能”的家庭。
  • 感谢您的回答,它解释了真正 MIPS 处理器的一切。但问题是我们在本课程中使用的程序集与 MIPS 类似,但不完全一样。我们的 BEQL 在延迟槽中执行分支目标的第一条指令 - 这里应该是 J QUIT。
  • @J.Doe 啊...从硬件设计的角度来看,这没有多大意义(我的意思是,在保持多级管道的同时创建这样的 CPU 几乎是不可能的)优势,从目标地址解码指令将迫使性能接近经典单指令处理的水平),但如果你的 CPU 是这样设计的,那么我反对谁......但正确的答案是使用 @987654338 @ 作为分支延迟槽指令。所以出了点问题。问讲师,什么是正确的?
猜你喜欢
  • 2015-03-28
  • 2011-10-17
  • 2011-06-03
  • 1970-01-01
  • 2013-11-18
  • 1970-01-01
  • 2013-10-09
  • 2021-07-10
  • 2015-09-09
相关资源
最近更新 更多