2011-08-08 19 views
1

SSEとSSE2の新機能です.2つのカウンタを割り当て、2つのカウンタを割り当てることで、2つのカウンタを割り当てることができます。私は組み込み関数とMicrosoft Visual Studio 10 C++ Expressを使用しました。第二段階として、何が起こっているのか理解したかったのですが、今私は困惑しています。 例えば、ループの中の割り当て動作にコンパイル:私は最初の2行はXMM0レジスタへのa_alignedアドレスの構成要素、及び第三のラインのコピーを取得することを理解組み込み関数を使用したSSE2アセンブリのオーバーフロー

__m128i a_ptr = _mm_load_si128((__m128i*)&(a_aligned[i])); 
mov   eax,dword ptr [i] 
mov   ecx,dword ptr [a_aligned] 
movdqa  xmm0,xmmword ptr [ecx+eax*2] 
movdqa  xmmword ptr [ebp-1C0h],xmm0 
movdqa  xmm0,xmmword ptr [ebp-1C0h] 
movdqa  xmmword ptr [a_ptr],xmm0 

。しかし、xmm0よりも(a_ptrよりも)メモリにコピーされた理由を理解できません。しかし、_mm_load_si128組み込み関数は、a_aligned [i]の128ビットをxmm0にコピーする必要があります。なぜこれが起こったのですか?私は理論的に間違っていますか?コンパイラのヒントはどうすればいいですか?私のサンプルコードは正しいですか(不必要なことがないという意味で)?あなたのコンパイラ設定で最適化の

#include <xmmintrin.h> 
#include <emmintrin.h> 
#include <iostream> 

int main(int argc, char *argv[]) { 
    unsigned __int16 *a_aligned = (unsigned __int16 *)_mm_malloc(32 * sizeof(unsigned __int16),16); 
    unsigned __int16 *b_aligned = (unsigned __int16 *)_mm_malloc(32 * sizeof(unsigned __int16),16); 
    unsigned __int16 *c_aligned = (unsigned __int16 *)_mm_malloc(32 * sizeof(unsigned __int16),16); 

    for(int i = 0; i < 32; i++) { 
     a_aligned[i] = i; 
     b_aligned[i] = i; 
     c_aligned[i] = 0; 
    } 

    for(int i = 0; i < 32; i+=8) { 
     __m128i a_ptr = _mm_load_si128((__m128i*)&(a_aligned[i])); 
     __m128i b_ptr = _mm_load_si128((__m128i*)&(b_aligned[i])); 
     __m128i res = _mm_add_epi16(a_ptr, b_ptr); 
     _mm_store_si128((__m128i*)&(c_aligned[i]), res); 
    } 

    for(int i = 1; i < 32; i++) { 
     std::cout << c_aligned[i] << " "; 
    } 

    _mm_free(a_aligned); 
    _mm_free(b_aligned); 
    _mm_free(c_aligned); 
    return 0; 
} 

答えて

1

電源を入れます(代わりに、デバッグのリリース構成を使用): はここに私の完全なサンプルコードです。

+0

ああ、このような愚かなエラー、mea culpa。ありがとうございました。 – WebMonster

+0

誰にも起こりますが、汗をかくことはありません。 –

2

コンパイラコードジェネレータがコードを最適化するのに役立つように、組み込み関数が明示的に設計されています。デバッグ設定で生成されたアセンブリコードが表示されています。それは最適化されたコードではありません。リリースビルドのコードを見てください。

 __m128i a_ptr = _mm_load_si128((__m128i*)&(a_aligned[i])); 
011D10A0 movdqa  xmm0,xmmword ptr [eax] 
     __m128i b_ptr = _mm_load_si128((__m128i*)&(b_aligned[i])); 
011D10A4 movdqa  xmm1,xmmword ptr [edx+eax] 
     __m128i res = _mm_add_epi16(a_ptr, b_ptr); 
011D10A9 paddw  xmm0,xmm1 
     _mm_store_si128((__m128i*)&(c_aligned[i]), res); 
011D10AD movdqa  xmmword ptr [ecx+eax],xmm0 

もっとよく見えますか?

+0

ありがとう、あなたの答えはStephen Canonと同じくらい役に立ちましたが、彼は最初に答えました。 – WebMonster

+0

うん、それはあなたが答えを文書化する努力をするときに起こります。問題ではなく、他の人が役に立つと思うかもしれません。 –

関連する問題