【问题标题】:Optimizing MIPS assembly优化 MIPS 组装
【发布时间】:2016-04-29 02:38:44
【问题描述】:

我正在尝试通过减少指令来优化 MIPS 代码。现在,我有一个这样的while循环:

funct: add  $v0, $zero, 0
       add  $t0, $zero, 0
Loop:  slt  $t1, $t0, $a0
       beq  $t1, $zero, Exit
       add  $v0, $v0, $t0
       addi $t0, $t0, 1
       j    Loop
Exit:  jr   $ra

我知道这相当于一个简单的 while 循环。但是,我很困惑如何将其转换为 do-while 循环以减少程序的执行。

【问题讨论】:

    标签: assembly optimization while-loop mips do-while


    【解决方案1】:

    这看起来像是一道家庭作业题,所以我将尝试为你指出正确的方向,而不是用勺子喂你答案。

    不要让你的条件跳转问“我们完成了吗”,考虑一下如果条件反转为“我们应该继续前进”你可以做什么。

    【讨论】:

      【解决方案2】:

      如果一个循环可能需要运行 0 次,则在循环之外放置一个条件分支以检查这种情况。

      您还可以在循环外放置一些指令来设置(或实际执行其中一些)第一次迭代。另一个技巧是跳到循环的中间而不是落入第一条指令。我不确定这种技术是否有名称。 (维基百科将software pipelining 定义为更复杂的东西,它会增加代码大小,而不是仅仅在循环内部旋转指令序列同时调整外部代码以匹配。)

      然后重组以将循环条件放在底部很简单:反转检查,以便在适当的时候退出循环,而不是让分支退出。


      如果你真的想减少执行的指令数量,你可以做一些数学运算并消除循环。 $t0 = 0 .. $a-1,然后每次迭代都将其添加到 $v0。所以循环只是一个总和(0..$a-1)。 sum(0..n) 有一个封闭式公式:n * (n+1) / 2

      请注意,转换循环时可以跳过 $t0 = 0 迭代(如果您决定保留它),因为 0 是加法标识。

      【讨论】:

      • 我在Why are loops always compiled into "do...while" style (tail jump)? 上的回答更详细地介绍了同一概念。也尝试询问编译器。 (在具有分支延迟槽的真正 MIPS 上,您需要填充延迟槽。当循环真的很小时可能很难,但是 OTOH 没有太多不同的可能性需要考虑......直到您开始考虑剥离一些第一次和/或最后一次迭代,因此您可以“旋转”循环以使分支条件位于底部,即使这不是循环逻辑的最自然形式。)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多