3

我正在尝试以正确的方式优化此代码。我所说的正确是......我想有一种通用的方法来执行这些优化,这样如果其他人查看代码,他们将能够删除优化。

C 代码示例以提高可读性...

int a = 1; // mapped to %l0
int b = 5; // mapped to %l1
int c = 0; // mapped to %l2
int d;     // mapped to %l3

while( a < b ) {
  c += a * b;
  ++a;
}

d = c * b;

SPARC 汇编版本...

  mov    %g0, %l2

  cmp    %l0, %l1
  bge    END_LOOP
  nop

LOOP:
  mov    %l0, %o0
  call   .mul
  mov    %l1, %o1       ! Fill delay slot with second argument
  add    %l2, %o0, %l2
  inc    %l0

  cmp    %l0, %l1
  bl     LOOP
  nop

END_LOOP:
  mov    %l2, %o0
  call   .mul           ! Fill delay sot with second argument
  mov    %l1, %o1

  mov    %o0, %l3

我可以优化第一部分(不确定是否正确),但我不确定如何优化第二部分。

  mov    %g0, %l2

  cmp    %l0, %l1
  bge,a  END_LOOP       ! Annul branch to execute if branch is taken
  mov    %l2, %o0       ! Instruction at target

LOOP:
  mov    %l0, %o0
  call   .mul
  mov    %l1, %o1       ! Fill delay slot with second argument
  add    %l2, %o0, %l2
  inc    %l0

  cmp    %l0, %l1
  bl     LOOP
  nop

  mov    %l2, %o0       ! Move the instruction to above the target

END_LOOP:
  call   .mul           ! Fill delay sot with second argument
  mov    %l1, %o1

  mov    %o0, %l3

任何有关如何执行这些优化的帮助将不胜感激。

4

1 回答 1

3

一般来说,你的方法是正确的。假设您没有紧跟目标的数据依赖或控制指令转移,您通常可以遵循以下约定。

你这样做了,可能没有意识到:

转到分支的目标,将指令复制到延迟槽中并取消分支。如您所述,如果未采用分支,则取消分支​​以防止指令执行。然后将指令移动到标签上方的目标处。

在您的代码中,按照上述步骤,您将执行以下操作:

我删除了您的评论,以便您可以清楚地看到我所做的更改。

  mov    %g0, %l2

  cmp    %l0, %l1
  bge,a  END_LOOP
  mov    %l2, %o0

  mov    %l0, %o0       ! 3. Move the instruction formerly after the loop
                        ! above the label
LOOP:
  [ mov    %l0, %o0 ]   ! Instruction was here

  call   .mul
  mov    %l1, %o1
  add    %l2, %o0, %l2
  inc    %l0

  cmp    %l0, %l1
  bl,a   LOOP           ! 1. Go to the target and copy that instruction into
                        ! they delay slot.
                        ! 2. Annul the branch
  mov    %l0, %o0       ! Instruction formerly after LOOP:

  mov    %l2, %o0

END_LOOP:
  call   .mul
  mov    %l1, %o1

  mov    %o0, %l3

如果您仔细检查代码,您会发现逻辑仍然成立,并且有一种系统化的方法来展开优化。

无论您是否进入循环,您的代码仍将正确执行循环之后的代码。

这是优化代码的一般方法,类似于编译器将执行的操作。关键始终是确保不存在数据依赖关系。

于 2013-06-29T16:46:12.313 回答