2011-08-08 47 views
1

我是SSE和SSE2的新手,我寫了一個小C樣本(分配兩個計數器,其中一個遞增,另一個遞減)。我使用了intrinsics和Microsoft Visual Studio 10 C++ Express。作爲第二步,我想了解引擎蓋下發生了什麼,但我現在感到困惑。 例如,對於循環的分配操作編譯爲:使用內在函數的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 

據我瞭解,前兩行得到a_aligned地址的組成部分,而第三線將其複製到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

打開你的編譯器設置優化(使用Release配置,而不是調試)。

+0

哦,這樣一個愚蠢的錯誤,mea culpa。謝謝。 – WebMonster

+0

適合每個人,不要爲此而出汗。 –

2

爲了幫助編譯器代碼生成器更好地優化代碼,明確設計了內在函數。您正在查看由Debug配置生成的彙編代碼。這不是優化的代碼。查看發佈版本中的代碼:

 __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's一樣有用,但他是第一個回答的人。 – WebMonster

+0

是的,當你通過記錄答案的努力時會發生這種情況。不是一個問題,其他人可能會覺得它有用。 –