assembly - 关于 MIPS 中 beq 的数据危害和转发?
问题描述
为什么第一个add
需要转发?
# stage:
add $1, $2, $3 # WB
add $4, $5, $6 # MEM
nop # EX
beq $1, $4, target # ID
既然beq
需要$1
,如果第一个add
即将执行WB-stage,那是不是因为ID-stage不需要转发beq
,即将读取寄存器文件?beq
我的书说需要转发之前的第二条和第三条指令以避免数据危险。
编辑:我在此链接幻灯片第 11 页上找到了我的意思;另一张幻灯片通过另一种技术特殊硬件解决了我的另一个困惑,即第一个add
不需要,幻灯片第 58 页。
解决方案
在同步数字系统中,在一个周期内,有两个不同的阶段。在第一阶段,通过运算符读取和转换操作数。在第二阶段,结果数据被写入寄存器。根据实现的不同,这些阶段可以对应于前半个周期和后半个周期,或者对应于整个周期和时钟的上升沿。
在任何一种情况下,重要的方面是可以读取(在第一阶段)和修改(最后)相同的寄存器。这就是为什么可以执行以下操作的原因
pc <= pc+4
在一个周期内。
在你提出的问题中,这正是发生的事情。
那个行动
add $1, $2, $3 # WB
将在第一阶段读取带有结果的流水线寄存器,并在周期结束时写入 $1。尽管
beq $1, $4, target # ID
将在第一阶段读取 $1 和 $4 并在循环结束时将结果写入 ppline 寄存器。因此,在没有转发的情况下,将写入之前的 $1 值。
(根据下面的评论编辑)
所有这些解释都是正确的,分支是用标准硬件处理的。在这种情况下,比较由 ALU 在“EX”阶段完成,PC 在此阶段结束时更新。
但这会导致两个周期的分支惩罚。为了减少这种损失,可以添加硬件来在 ID 阶段执行比较。在这种情况下,如果比较需要计算一个值(在您的示例中为 $1),则需要停顿。
推荐阅读
- javascript - On Scroll - 添加类 - 对于页面上的每个元素
- node.js - Nodejs Redis Scan不返回所有项目
- c++ - 如何将“IF CONDITION”重写为 ON 3 分钟和 OFF 10 分钟直到 4 小时(240 分钟)
- android - ViewModel 和 LiveData 观察者未调用
- google-cloud-dataflow - CDAP DataFusion GET 管道运行无效 IAP 凭证错误
- spring - 基于 Java 的 ETL 应用程序
- perl - Perl - 匹配文件中的开始/结束字符串
- python - 字典推导中 for 循环的 in 关键字如何工作?
- django - Django 3.0.7 版,/cart/ 'cart' 处的 TemplateSyntaxError 不是已注册的标签库
- python - 使用 python 龟的乒乓球游戏不工作