0

私は解釈を構築し、Cで書き、GCCを使用しています。

中間コードを生成する方法を変更しました。

しかし、このコードの解釈で予想外の変化が起こりました。中間コードで条件付きジャンプを処理する条件ブロックが 1 つあります。私はそのコードを変更しませんでした。

Dissyを使って分解。

古いバージョンのアセンバーは次のようになります。

mov  0x10(%r14),%rax
mov  0x50(%rsp),%rcx
mov  (%rcx,%rax,8),%r12
mov  (%r12),%eax
test $0x4,%al
je   4077ef
cmpb $0x0,0x8(%r12)
je   4077ef

新しいバージョン:

mov  0x10(%r14),%rax
mov  (%r12,%rax,8),%rdx
mov  (%rdx),%eax
test $0x4,%al
je   4073e0
cmpb $0x0,0x8(%rdx)
je   4073e0

この変更により、予測ミスが原因でパフォーマンスが 4 ~ 6% 低下しました。

移植性を維持するために、GCC がアセンブリ セクションを使用せずに古いバージョンを使用することを提案する方法はありますか?

ありがとう。

編集

C のコード:

if((M->type & 4 && M->val.boolean)
|| (M->type & 1 && M->val.number != 0.0)
|| (M->type & 2 && M->val.string.length != 0))
    // true;
else
    // false;
4

1 に答える 1

2

ここでは、分岐予測に違いはありません。

むしろ、元のソースコードを次の場所から変更したようです。

 void my_func( int *myarray, int N) {
      do_something(myarray[N]);
 }

 void modified( int * myarray, int N) {
     do_something(myarray);
     do_something_else(myarray[N]);
 }

後者の場合、myarrayのベースはすでにレジスタr12にキャッシュされているため、または関数のパラメータとして使用するためにmyarrayをローカルスタックから移動したばかりであるためです。

于 2012-12-03T11:15:38.433 に答える