我試圖利用由knc(Xeon Phi)提供的SIMD 512來提高使用intel intrinsics的以下C代碼的性能。然而,我的內在的嵌入代碼的運行速度比自動向量化代碼在KNC(Xeon Phi)中查找矢量數組中的數字實例
C代碼
int64_t match=0;
int *myArray __attribute__((align(64)));
myArray = (int*) malloc (sizeof(int)*SIZE); //SIZE is array size taken from user
radomize(myArray); //to fill some random data
int searchVal=24;
#pragma vector always
for(int i=0;i<SIZE;i++) {
if (myArray[i]==searchVal) match++;
return match;
內在嵌入代碼慢: 在下面的代碼,我第一次加載陣列,並將其與搜索鍵比較。內部函數返回使用_mm512_mask_reduce_add_epi32()減少的16位掩碼值。
register int64_t match=0;
int *myArray __attribute__((align(64)));
myArray = (int*) malloc (sizeof(int)*SIZE); //SIZE is array size taken from user
const int values[16]=\
{ 1,1,1,1,\
1,1,1,1,\
1,1,1,1,\
1,1,1,1,\
};
__m512i const flag = _mm512_load_epi32((void*) values);
__mmask16 countMask;
__m512i searchVal = _mm512_set1_epi32(16);
__m512i kV = _mm512_setzero_epi32();
for (int i=0;i<SIZE;i+=16)
{
// kV = _mm512_setzero_epi32();
kV = _mm512_loadunpacklo_epi32(kV,(void*)(&myArray[i]));
kV = _mm512_loadunpackhi_epi32(kV,(void*)(&myArray[i + 16]));
countMask = _mm512_cmpeq_epi32_mask(kV, searchVal);
match += _mm512_mask_reduce_add_epi32(countMask,flag);
}
return match;
我相信我有一些如何引入額外的週期在這段代碼,因此它正在運行緩慢相比,自動向量化代碼。與SIMD128直接返回128位寄存器中的比較值不同,SIMD512返回掩碼寄存器中的值,這增加了我的代碼的複雜性。我在這裏錯過了什麼,必須有出路才能直接比較並保持成功搜索的次數,而不是使用諸如異或操作的掩碼。
最後,請建議我使用內在函數來提高此代碼性能的方法。我相信我可以使用內在函數來榨取更多性能。對於SIMD128來說,這至少是正確的,在SIMD128中,使用內在函數使我獲得25%的性能。
爲什麼使用兩個負載來填充'kV'?爲什麼不只是一個'_mm512_load_epi32'? –