2

Win32 で GUI アプリケーションに C++builder を使用しています。Borland コンパイラの最適化は非常に悪く、SSE の使い方がわかりません。mingw gcc 4.7 でコンパイルすると 5 倍高速になる関数があります。Borland コンパイラではインライン アセンブラが許可されているため、gcc にアセンブラ コードを生成してから、C 関数内でこの cod を使用するように依頼することを考えています。

C の関数は次のようになります。

void Test_Fn(double *x, size_t n,double *AV, size_t *mA, size_t NT)
{
double s = 77.777;
size_t m = mA[NT-3];
AV[2]=x[n-4]+m*s;
}

質問を単純化するために、関数コードを非常に単純にしました。私の実際の機能には多くのループが含まれています。

Borland C++ コンパイラは、次のアセンブラ コードを生成しました。

  ;
  ; void Test_Fn(double *x, size_t n,double *AV, size_t *mA, size_t NT)
  ;
  @1:
push      ebp
mov       ebp,esp
add       esp,-16
push      ebx
 ;
 ;  {
 ;      double s = 77.777;
 ;
mov       dword ptr [ebp-8],1580547965
mov       dword ptr [ebp-4],1079210426
 ;
 ;      size_t m = mA[NT-3];
 ;
mov       edx,dword ptr [ebp+20]
mov       ecx,dword ptr [ebp+24]
mov       eax,dword ptr [edx+4*ecx-12]
 ;
 ;      AV[2]=x[n-4]+m*s;
 ;
 ?live16385@48: ; EAX = m
xor       edx,edx
mov       dword ptr [ebp-16],eax
mov       dword ptr [ebp-12],edx
fild      qword ptr [ebp-16]
mov       ecx,dword ptr [ebp+8]
mov       ebx,dword ptr [ebp+12]
mov       eax,dword ptr [ebp+16]
fmul      qword ptr [ebp-8]
fadd      qword ptr [ecx+8*ebx-32]
fstp      qword ptr [eax+16]
 ;
 ;  }
 ;
 ?live16385@64: ;
 @2:
pop       ebx
mov       esp,ebp
pop       ebp
ret

gcc で生成されたアセンブラー コードは次のとおりです。

 _Test_Fn:
mov edx, DWORD PTR [esp+20]
mov eax, DWORD PTR [esp+16]
mov eax, DWORD PTR [eax-12+edx*4]
mov edx, DWORD PTR [esp+8]
add eax, -2147483648
cvtsi2sd    xmm0, eax
mov eax, DWORD PTR [esp+4]
addsd   xmm0, QWORD PTR LC0
mulsd   xmm0, QWORD PTR LC1
addsd   xmm0, QWORD PTR [eax-32+edx*8]
mov eax, DWORD PTR [esp+12]
movsd   QWORD PTR [eax+16], xmm0
ret
 LC0:
   .long    0
   .long    1105199104
   .align 8
 LC1:
   .long    1580547965
   .long    1079210426
   .align 8

gcc と Borland C++ で関数の引数へのアクセスがどのように行われるかについてのヘルプを得るのが好きです。Borland の C++ での私の関数は次のようになります。

 void Test_Fn(double *x, size_t n,double *AV, size_t *mA, size_t NT)
 {
__asm
  {
  put gcc generated assembler here
  }
 }

Borland はebp、gcc がレジスタを使用している間にレジスタを使用し始めespます。cdecl ou stdcall のようないくつかの呼び出し規則を使用して、引数にアクセスするための互換性のあるコードをコンパイラの 1 つに生成させることはできますか?

4

3 に答える 3

1

すべてを GCC でコンパイルするか、重要なファイルだけを GCC でコンパイルし、残りを Borland でコンパイルして、リンクが機能するかどうかを確認します。あなたが説明したことは機能させることができますが、それはおそらくあなたが投資した時間の価値がない難しい仕事です(非常に多くのマシンで非常に頻繁に実行される場合を除きます).

于 2013-04-07T23:53:27.817 に答える