首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >序列重新排序以解决RISC-V汇编中的数据风险

序列重新排序以解决RISC-V汇编中的数据风险
EN

Stack Overflow用户
提问于 2020-10-07 12:38:22
回答 1查看 155关注 0票数 2

对于下面的RISC-V代码序列,我尝试识别无法通过数据转发解决的数据风险。有没有可能通过重新排序代码序列来克服这些风险?如果是,谁能展示新的序列?

下面是我的代码:

代码语言:javascript
复制
loop: slli  s2, s1, 2
      add   s3, s2, s0
      lw    t0, 0(s3)
      add   t1, t2, t0
      sw    t1, 20(s3)
      addi  s1, s1, 1
      beq   s1, s5, loop
EN

回答 1

Stack Overflow用户

发布于 2020-10-09 01:13:28

哪些数据风险可以通过转发解决,这完全取决于您正在使用的RISC-V架构的特定实现。我将假设Patterson & Hennessey教科书中提出的具有转发功能的传统5阶段RISC-V流水线,并尝试回答您的问题。

此流水线具有取指令(IF)、指令解码(ID)、执行(EX)、内存(MEM)和回写(WB)阶段。执行级计算寄存器-寄存器和寄存器-立即操作的值,并计算存储器( lw / sw )和控制转移(分支/跳转)操作的地址,而存储器级读取lw的数据并写入sw的数据。可以将数据从执行、存储器或写回级的末尾转发到用于后续指令的前一级的开头。

在您包含的代码片段中,会有5种数据风险:

(1) slli s2, s1, 2add s3, s2, s0,用于寄存器s2

这里,寄存器s2slli写入,由add读取。新值是在第一条指令的EX阶段结束时计算的,并且在下一条指令的EX阶段开始时需要,因此可以通过转发来解决。

(2)用于寄存器s3add s3, s2, s0lw t0, 0(s3)

这里,寄存器s3add写入,由lw读取。新值是在第一条指令的EX阶段结束时计算的,并且在下一条指令的EX阶段开始时需要,因此可以通过转发来解决。

(3)用于寄存器t0lw t0, 0(s3)add t1, t2, t0

这里,寄存器t0lw写入,由add读取。新值是在第一条指令的内存阶段结束时计算的,并且在下一条指令的EX阶段开始时需要,因此it canNOT可以通过转发来解析。

(4)用于寄存器t1add t1, t2, t0sw t1, 20(s3)

这里,寄存器t1add写入,由sw读取。新值是在第一条指令的EX阶段结束时计算的,并且在下一条指令的MEM阶段开始时需要,因此可以通过转发来解决。

(5)用于寄存器s1addi s1, s1, 1beq s1, s5, loop

这里,寄存器s1addi写入,由beq读取。新值在第一条指令的EX阶段结束时计算。通常,对于没有针对控制风险进行任何优化的RISC-V流水线,对于分支指令,在计算程序计数器+偏移量的同时,在EX期间比较寄存器以获得分支目的地。这里的控制风险是一个单独的问题,但数据风险可以通过转发来解决。

因此,在这5种危险中,只有一种是无法通过数据转发解决的。它可以通过指令重新排序来解决吗?是。看看addi s1, s1, 1吧。在addi之前,第一个slli之后的任何指令都不会读取或写入s1。如果我们移动该指令,那么结果代码如下所示:

代码语言:javascript
复制
loop: slli  s2, s1, 2
      add   s3, s2, s0
      lw    t0, 0(s3)
      addi  s1, s1, 1
      add   t1, t2, t0
      sw    t1, 20(s3)
      beq   s1, s5, loop

这样,当lw指令需要新值t0时,检索要写入t0的数据的add t1, t2, t0指令就已经完成了内存阶段。

通过这种重新排序,所有数据风险都可以通过转发来解决,并且不需要停顿。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64237292

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档