【问题标题】:MIPS bne beq Computer Organization and DesignMIPS bne beq 计算机组织与设计
【发布时间】:2012-12-15 18:22:21
【问题描述】:

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

将 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 寄存器不等于指令(bne):

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

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

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

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

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

【问题讨论】:

  • 我没有看到任何问题,但这是很多假设,没有太多支持......
  • 我认为很少有任何条件分支比另一个更“有效”(至少对于通用寄存器和标志 - 一些系统/控制/专用寄存器/标志可能有相关的性能损失)。可能bne 被视为“更有效”的原因可能是一种心理原因,编码人员倾向于编写if (most_likely_condition) something(); else something_else(); 形式的代码。再加上无分支代码对缓存更友好,可能会使“相反条件”“更有效”。
  • 说清楚(我会在一分钟内编辑我的帖子):教科书字面上说 bne 会更有效,我的问题是为什么。我不假设任何东西来证明它们是错误的,我只是提出了一些理论,为什么 bne 和 beq 可能具有不同的效率,但是应用于此示例的这些理论中的每一个都导致 bne 效率不高。
  • 我最近也在看这本教材。它真的帮助我了解计算机体系结构的想法。

    我有一个假设,效率的差异来自bnebeq机器代码的直接比较

    考虑两条指令正在比较两个寄存器。 beq 的操作必须经过每一位给出答案并将其存储到目标寄存器中。另一方面,bne 可能会抵消前几个的差异。

    我没有任何确凿的证据支持这个假设。如果有人可以支持或操作,我真的很高兴

标签: assembly branch conditional mips


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

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

    最短的路径是通过比较,失败而不是跳转。

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

    不常见的分支案例

    beq 18 美元,19 美元,L1

    • 其他处理

    • jmp

    替换为

    18 美元,19 美元,L2

    • 成功处理

    • 结束

    L2:

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

    重新阅读您的问题,我认为症结在于这个假设:

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

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

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

    【讨论】:

    • 编辑:我无法使用这个东西,不知道如何换行。我相当肯定我正在遵循您的逻辑(因为快速处理常见情况是我试图做的,只是忘了这样解释),但我不确定我是否完全明白。我会引用你的话:“如果你假设值更可能不相等,那么在使用 bne 时只需要处理一条指令,如果你使用 beq,你必须在失败时执行额外的跳转。”不是正好相反吗?如果它们相等,beq 会跳转,所以如果您不希望它们相等,您应该使用 bne 我认为?
    • 我不得不考虑一下,这个想法是,如果您希望这些值不相等,则使用 bne,因为只会遵循一条指令。如果您希望它们相等,请使用 beq。当任一比较失败时,您有一个额外的指令 - 跳转。编写代码,以便尽可能少地使用“失败”跳转。
    • 不要让我混淆你或我自己。与 bne 或 beq 进行比较的成本将相同,效率将来自最小化代码路径
    • 是的,但我对以下内容完全感到困惑:我想说,如果您希望值相等,您会使用 bne (因为 bne 意味着跳跃不相等,如果你期望相等),但你说如果我期望它们相等我应该使用 beq,我很困惑。
    • 是的,我同意这令人困惑。我记得它的目标是最少跳。正如上面 twalberg 所说,我们倾向于测试成功,通过测试意味着我们跳跃。我希望代码在比较之后失败 - 留在本地。测试失败,以便代码在我们想要使用的值上失败,在意外情况下分支,失败时。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-04
    • 2012-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-20
    相关资源
    最近更新 更多