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

最初の部分は最適化できますが (正しいかどうかはわかりません)、2 番目の部分を最適化する方法がわかりません。

  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 に答える