2013-01-10 57 views
1

哪些代碼可以利用SIMD指令集的嚴格定義是什麼?是否可以並行運行計算?支持SIMD的代碼?

所以,如果我有:

for(int i=0; i<100; i++){ 
    sum += array[i]; 
} 

這可能需要SIMD的優勢,因爲我們可以運行:

for(int i=0; i<100;i=i+4){ 
    sum0 += array[i]; 
    sum1 += array[i+1]; 
    sum2 += array[i+2]; 
    sum3 += array[i+3]; 
} 

sum = sum0 + sum1 + sum2 + sum3; 

它是否必須是浮點類型,或者它可能是雙精度和整數?

+2

確實沒有任何有用的定義。你可以在使用它時使用它 - 它只能由經驗來回答。 – harold

回答

4

假設你正在談論的x86(SSE ),則支持的類型爲算術是8,16,32和64位整數,並將單精度和雙精度浮點數。但請注意,並非所有數據類型都支持所有算術運算 - SSE在這方面缺乏正交性。

假設32個整數並且適當對齊陣列(16字節對齊),那麼你可以實現的上述循環例如作爲:

#include <emmintrin.h>      // SSE2 intrinsics 

int32_t a[100] __attribute__ ((aligned(16))); 
              // suitably aligned array 

__m128i vsum = _mm_set1_epi32(0);   // init vsum = { 0, 0, 0, 0 } 
for (int i = 0; i < 100; i += 4) 
{ 
    __m128i v = _mm_load_si128(&a[i]);  // load 4 ints from a[i]..a[i+3] 
    vsum = _mm_add_epi32(vsum, v);   // accumulate 4 partial sums 
} 
// final horizontal sum of partial sums 
vsum = _mm_add_epi32(vsum, _mm_srli_si128(vsum, 8)); 
int32_t sum = _mm_cvtsi128_si32(vsum);  // sum = scalar sum of a[] 
+0

謝謝你的保羅。你能否爲我澄清一些事情?關於對齊,這是SSE/AVX擴展類型照顧程序員的東西嗎?或者是我們必須要做的事情,如果是的話,這是如何完成的?我認爲你指的是填充字節? – user997112

+1

基本SIMD數據類型(例如'__m128i')會自動對齊,但對於非SIMD數據類型和動態內存分配('new','malloc'等),則需要格外小心以確保對準。如果您的數據由於某種原因無法正確對齊,那麼您可以使用未對齊的SIMD加載/存儲作爲最後的手段,但是會對此產生性能損失。 –

+0

爲什麼動態內存分配會受到關注?我們是不是隻處理「原始」SSE類型(「8,16,32和64位整數,以及單精度和雙精度浮點數」)? – user997112