2010-12-09 66 views
-1

以下循環執行數百次。
elma and elmc are both unsigned long (64-bit) arrays, so is res1 and res2.SIMD代碼和標量代碼

unsigned long simdstore[2]; 
__m128i *p, simda, simdb, simdc; 
p = (__m128i *) simdstore; 

for (i = 0; i < _polylen; i++) 
{ 

    u1 = (elma[i] >> l) & 15; 
    u2 = (elmc[i] >> l) & 15; 
    for (k = 0; k < 20; k++) 
    {  

    1. //res1[i + k] ^= _mulpre1[u1][k]; 
    2. //res2[i + k] ^= _mulpre2[u2][k];    
    3.  _mm_prefetch ((const void *) &_mulpre2[u2][k], _MM_HINT_T0); 
    4.  _mm_prefetch ((const void *) &_mulpre1[u1][k], _MM_HINT_T0); 
    5.  simda = _mm_set_epi64x (_mulpre2[u2][k], _mulpre1[u1][k]); 
    6.  _mm_prefetch ((const void *) &res2[i + k], _MM_HINT_T0); 
    7.  _mm_prefetch ((const void *) &res1[i + k], _MM_HINT_T0); 
    8.  simdb = _mm_set_epi64x (res2[i + k], res1[i + k]); 
    9.  simdc = _mm_xor_si128 (simda, simdb); 
    10.  _mm_store_si128 (p, simdc); 
    11.  res1[i + k] = simdstore[0]; 
    12.  res2[i + k] = simdstore[1];      
    }  
} 

在for循環中,標量版本的代碼(註釋)運行速度比simd代碼快兩倍。以上提到的cachegrind輸出(指令讀取)如下。

第1行:668460000 2 2
第2行:668460000 1 1
第3行:89985000 1 1
第4行:89985000 1 1
第5行:617040000 2 2
第6行:44992500 0 0
第7行:44992500 0 0
第8行:539910000 1 1
第9行:128550000 0 0
第10行:。 。 。
第11行:205680000 0 0
第12行:205680000 0 0

從上面的圖,它顯示了註釋(標量的代碼)需要更少顯著比SIMD代碼指令數目。

這段代碼如何能更快?

+0

這是你自己問題的重複。回到那裏,理解爲什麼這個答案(而不是你標記爲正確的答案)解決了這個問題:http://stackoverflow.com/questions/4394930/simd-code-runs-slower-than-scalar-code/4395337# 4395337 – 2010-12-09 12:27:29

回答

3

取出_mm_prefetch內在因素 - 他們在這種情況下什麼都沒有實現,甚至可能會傷害到表現。如果(a)您有空閒帶寬,並且(b)您可以在數據實際需要時提前數百個時鐘週期發出預取提示,則預取僅有益處。我認爲你的情況既不是(a)也不是(b)。

1

你peformance問題是這樣的:

_mm_set_epi64x(_mulpre2 [U2] [k]的,_mulpre1 [U1] [K]);

mm_set(a,b,c,d)類內在函數非常緩慢。 只有單參數集內在函數(aka廣播)速度很快。

我看着他們在彙編代碼中做了什麼。

他們基本上在堆棧上創建一個數組,使用正常的內存移動(mov DWORD),將您的兩個整數從它們當前駐留的多維數組移動到堆棧數組。然後從堆棧數組中使用XMM內存移動(mov XMWORD)。

標量版本直接從內存到寄存器。更快!

您看到開銷來自於XMM寄存器一次只能與128位通信這一事實,因此您的程序在加載它們之前先在另一個內存區域中排序128位。

如果有辦法將64位值直接移入或移出正常寄存器到XMM寄存器,我仍在尋找它。

爲了從使用SSE/XMM寄存器獲得速度提升,您的數據可能需要在內存中保持有序。如果您可以在無序加載的情況下執行多個XMM操作,則將無序數據裝載到XMM寄存器中是非常值得的。在這裏你做一個單獨的XOR操作。