为什么这两条指令被认为是数据相关的?

Why are these 2 instructions considered data dependent?

所以,我了解到,当我们在CPU中使用流水线技术时,我们可能必须解决一些危险,例如两条指令之间的数据依赖性。 例如,我确实得到了这个数据依赖性:

add $t0, $t1, $t2
lw $s1, 0($t0)

lw 确实需要 $t0 的正确结果 但是,我还看到,我们认为 那 2 条指令是数据相关的。 为什么?

    add $t0, $t1, $t2
    lw $s1, 4($t0)

因为 lw 确实需要 mem[$t0] + 4 的正确值,这是一个不同的地址,为什么这被认为是一个依赖项?也许,我不明白,$lw 在那里做什么?
我是这样想的:
比方说

  addi $t0,$t0, 5
  lw $s1, 0($t0) # now we loaded the value 5 to $s1
  
  #BUT WHAT ABOUT THAT
  li $t1, 9
  addi $t0, $t0, 5
  sw $t1, 4($t0) # now we go to &(mem[$t0]+4) and there we store the value of $t1, which is 9,  

我们需要 t0 的地址而不是它的值(或者至少我是这么理解的)

有人能给我解释一下吗?

We needed the adress of t0

寄存器没有地址:它们有名字;它们在寄存器文件中有 positions/index,并且它们保存值。

只有内存有地址。

Since, lw, does need the correct value of mem[$t0] + 4

lw 访问 mem[$t0+4],它需要 $t0 的值才能执行 +


lwsw指令计算有效地址:

ea = R[rs]+SignExtImm

这里,硬件正在索引寄存器文件,使用索引 rs,它是从编码指令中名为 rs 的 5 位字段获得的,lw.存储在寄存器中的值是 32 位的,因此 5 位索引用于查找保存在那里的 32 位值。因此,这是对寄存器 rs 值的读取。立即数从指令字段中的 16 位符号扩展到 32 位,然后寄存器的 32 位值和立即数都被提供给 ALU 以加在一起。

计算 ea 后,负载为:

R[rt] = M[ea]

并且在计算 ea 之后,商店会

M[ea] = R[rt]

为了计算 ea,我们需要 R[rs] 的值,即保存在 rs 寄存器中的值。


这部分操作几乎与序列相同:

add $t0, $t1, $t2   # $t0 is written here
addi $s1, $t0, 4    # $t0 is read, ALU computes $t0+4 (result goes to $s1)
lw $s2, 4($t0)      # $t0 is read, ALU computes $t0+4 (result is a memory address)
xori $s3, $t0, 8    # $t0 is read, ALU computes $t0^8

addaddi 对已读取正确的数据依赖性。这是 ALU/ALU 依赖项还是 EX/EX 取决于我们是在谈论功能单元还是管道阶段。这些都是背靠背的危险。

由于寄存器读取通常发生在 ID(指令解码)阶段,如果通过 WB(回写)阶段 rs 的最后一次寄存器更新是一条提前 3 个周期开始的指令,那么这个 ID 读取的 rs 将选择正确的值。更少意味着读入的 ID 将看不到正确的值,因为它还没有进入寄存器。

cycle#:       1  2  3  4  5  6  7  8
instruction #
i1:          IF ID EX MM WB           
i2:             IF ID EX MM WB
i3:                IF ID EX MM WB
i4:                   IF ID EX MM WB

这里 i4 可以毫无危险地读取 i1 的寄存器更新,因为这些操作都发生在周期 5 中——i1 的 WB 发生在时钟 5 的开始,并且 i4 的 ID 能够看到写入相同的值时钟.

但是如果i2或者i3读取了i1指向的寄存器,那么就会有危险,因为他们的ID阶段发生在i1的WB阶段之前(i2的ID在第3周期,i3的ID在第4周期,都太早了在第 5 周期获得 i1 的 WB。

所以,危险就是这样发生的。但是请注意,i2 的 EX 阶段(在第 4 个周期)所需的正确值在 CPU 中,并且已经在第 3 个周期中由 i1 的 EX 阶段计算出来。转发或旁路替换该正确值以覆盖在 i2 或 i3 的 ID 阶段读取的陈旧值。


查看指令描述和编码的更多详细信息: https://inst.eecs.berkeley.edu/~cs61c/resources/MIPS_Green_Sheet.pdf

查看基本指令格式以查看字段编码,例如lwsw 都是 I 型指令,所以它们有一个 rs、一个 rt 和一个 immediate 字段。

lw指令有一个寄存器源和一个寄存器目标。 (它也有一个内存源,但我们不查看内存是否存在数据依赖性 Read-After-Write 危险,我们只查看寄存器。)

sw指令有两个寄存器源,没有寄存器目标。 (它也有一个内存目标,但我们不查看内存是否存在数据依赖性写后读危险,我们只查看寄存器。)