【问题标题】:How is an annulled branch different from a regular branch?取消的分支与常规分支有何不同?
【发布时间】:2010-10-10 21:16:55
【问题描述】:

特别是对于 SPARC 程序集,已取消的分支与常规分支有何不同?

我一直认为,当我需要填充分支指令的 nop 延迟槽时,需要取消分支指令。但是,我认为我在这部分上是不正确的,因为您可以在不取消分支的情况下填充 nop。

【问题讨论】:

    标签: optimization assembly sparc


    【解决方案1】:

    被取消的分支指令会导致延迟槽中的指令——分支之后的指令——如果不进行分支则被忽略。

    为什么这很重要?因为通常情况下,分支之后的指令都会被执行,即使是分支被取走。这是因为有两个程序计数器,PC 和 NPC。表示正在执行的指令的PC被更新为NPC,即PC+4,同时NPC被更新为分支指令的目标。因此,由于这些事件的时间安排,必须加载下一条指令。如果可以的话,使用这个循环比直接扔掉那个循环更有利可图。然后,我们只需将该指令作为循环的一部分。

    loop:   someOp                
            someOtherOp
            branch      loop      ;
            delayslotOp           ; will actually be executed, before someOp, after branch
    

    如果我们不能在分支之后使用指令槽,那么我们会在其中插入一个 nop,并且在那个循环中什么都不做。

    那么为什么会有不同的指令带有取消和非取消分支选项?让我们选择退出循环时会发生什么。如果我们将延迟槽作为循环活动的一部分,我们可能不希望在离开循环时执行该操作。因此,我们将在分支指令的末尾添加“,a”。

    This page has some nice examples.

    【讨论】:

      【解决方案2】:

      根据SPARC Architecture Manual (v9)

      3.2.3 控制转移

      [...]

      大部分控制转移指令都有延迟;也就是说,紧跟在 a 之后的指令 逻辑顺序中的控制转移指令在之前调度 控制转移到目标地址完成。

      [...]

      调用延迟控制转移指令之后的指令 延迟指示。延迟控制转移指令中的位 (取消位)可以导致延迟指令被取消(即 是,没有效果)如果没有采取分支。

      6.3.4 控制转移指令 (CTI)

      [...]

      编程说明:annul 位增加了 编译器可以找到一条有用的指令来填充延迟槽 分支,从而减少由一个执行的指令的数量 程序。例如,annul 位可用于移动指令 从循环中填充关闭分支的延迟槽 循环。同样,annul 位可用于移动指令 来自“ifthen-else”程序的“else”或“then”分支 阻塞到在它们之间选择的分支的延迟槽。自从 提供全套条件,编译器可以编排代码 (可能颠倒条件的意义)使得指令 从“else”分支或“then”分支都可以移动到 延迟槽。

      下面的代码显示了两个分支,第一个总是执行延迟指令,第二个如果不采取分支则取消延迟指令:

      cmp   %i3, %i0
      ble   %icc, -0x5c
      ld    [%l0 - 0x4], %i5  ; executed whether the branch is taken or not
      
      ...
      
      cmp   %l1, 0x80
      bl,a  %icc, +0x40
      ld    [%fp + 0x7c7], %g2    ; annulled if the branch is not taken, executed otherwise
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-12-23
        • 2021-12-21
        • 1970-01-01
        • 1970-01-01
        • 2021-10-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多