4

所以,我会引用我的教科书(计算机组织与设计),然后我会问我的问题:

将 if-then-else 编译成条件分支

在以下代码段中,f、g、j、i 和 j 是变量。如果 f 到 j 的五个变量对应于 $s0 到 $s4 的五个寄存器,那么这个 C if 语句的编译 MIPS 代码是什么?

如果 (i == j) f = g + h; 否则 f = g - h;

图 2.9 是 MIPS 代码应该做什么的流程图。第一个表达式比较相等,因此如果寄存器是相等指令(beq),我们似乎想要分支。一般来说,如果我们测试相反的条件来分支执行 if 的后续 then 部分的代码(标签 Else 在下面定义),代码会更有效,因此我们使用分支 if registers are not equal 指令(bne):

bne $s3, $s4, Else # 如果 i ≠ j 则转到 Else

我已经搜索了一段时间,但我找不到为什么 bne 会比 beq 更有效。(但我确实发现有时建议使用 bne,因为它使代码更容易理解,因为条件成立时要执行的语句就在 bne 语句的正下方。)

因此,如果一般来说它不会更有效,那么在这个特定的练习中它仍然可能更有效。我已经考虑过这一点,并且我假设跳转指令会花费时间,因此我们希望最大限度地减少所需的跳转量。这意味着,当我们期望条件成立时,我们应该使用 bne,而当我们期望条件不成立时,我们应该使用 beq。

现在,如果我们测试 $s3 是否等于 $s4,当我们没有关于这些寄存器内容的任何信息时,假设它们可能相等是不合理的;相反,它们更有可能不相等,这应该导致使用 beq 而不是 bne。

所以,总结一下:教科书说 bne 比 beq 更有效,无论是一般情况还是只是在这个例子中都不清楚,但无论哪种情况我都不明白为什么。

4

2 回答 2

1

效率不是来自 bne 与 beq 的机器代码的直接比较。文本描述了通过编码来优化整体性能以缩短最常见的代码路径。

如果您假设这些值更可能不相等,那么在使用 bne 时只需要处理一条指令,如果您使用 beq,则必须在失败时执行额外的跳转。

最短的路径是放弃比较,失败而不是跳跃。

来自http://www.cs.gmu.edu/~setia/cs365-S02/class3.pdf

分支机构的罕见案例

beq $18, $19, L1

  • 其他处理

  • 跳转

取而代之

bne $18, $19, L2

  • 成功处理

  • 结尾

二级:

快速处理常见情况 - 大多数分支的一条指令

重新阅读你的问题,我认为关键是这个假设:

“现在,如果我们测试 $s3 是否等于 $s4,当我们没有关于这些寄存器内容的任何信息时,假设它们可能相等是不合理的;相反,它们更有可能是不相等,这将导致使用 beq 而不是 bne。”

这似乎是一种混乱,我们需要找到一些证据或理由来确定哪种可能性更大,寄存器相等或不相等。

在这种情况下,我们正在检查 if-then-else。我断言我们期望 if 测试通过,这就是 twalberg 描述的心理学。寄存器不太可能包含随机值,因为它们包含程序员期望的数据 - 先前操作的结果。

于 2012-12-31T17:39:39.350 回答
0

另一个原因是简单的分支预测器通常假设不采用前向分支而采用后向分支。这个假设为简单的循环提供了更好的性能。

于 2013-01-01T23:40:44.123 回答