2011-11-02 49 views
1

我有一個非常簡單的程序,我試圖提高性能。我知道的一個方法是利用SSE3(因爲我工作的機器支持這一點),但我完全不知道如何去做。下面的代碼片段(C++):真正基本的SSE

int sum1, sum2, sum3, sum4; 
for (int i=0; i<length; i+=4) { 
    for (int j=0; j<length; j+=4) { 
    sum1 = sum1 + input->value[i][j]; 
    sum2 = sum2 + input->value[i+1][j+1]; 
    sum3 = sum3 + input->value[i+2][j+3]; 
    sum4 = sum4 + input->value[i+3][j+4];  
    { 
} 

我讀過一些關於這一點,並瞭解的想法,但我完全不知道如何實現這一點。有人可以幫我嗎?我認爲這很簡單,特別是對於我的簡單程序,但有時候入門是最難的部分。

謝謝!

回答

6

其實,就你而言,並不那麼簡單。就目前來看,您的代碼是不是可以進行矢量化。 (至少不是沒有顯着的循環轉換)

原因是你在內部循環中也改變了索引i。由於存儲位置不再相鄰,並且位於矩陣的不同行中,因此可以對矢量化迭代進行矢量化。 (因爲你似乎在對角線上跑下矩陣)

但是,我覺得你正試圖總結矩陣中的所有元素,並且你實際上是想讓你的循環像這樣(並且你有一些錯別字):

int sum1 = 0, sum2 = 0, sum3 = 0, sum4 = 0; 
for (int i=0; i<length; i++) { 
    for (int j=0; j<length; j+=4) { 
    sum1 = sum1 + input->value[i][j]; 
    sum2 = sum2 + input->value[i][j+1]; 
    sum3 = sum3 + input->value[i][j+2]; 
    sum4 = sum4 + input->value[i][j+3];  
    } 
} 

int total = sum1 + sum2 + sum3 + sum4; 

如果這是你想要的,那麼它是非常可以矢量化的。 在C/C++使用內部函數,這是可以做到只用SSE2如下:

__m128i sum = _mm_setzero_si128(); 
for (int i=0; i<length; i++) { 
    for (int j=0; j<length; j+=4) { 
    __m128i val = _mm_load_si128(&input->value[i][j]); 
    sum = _mm_add_epi32(sum,val); 
    } 
} 

注意,對齊限制將適用。通過進一步展開循環,可以獲得更多的加速。