我正在尝试利用 knc (Xeon Phi) 提供的 SIMD 512 来使用 intel 内在函数来提高以下 C 代码的性能。但是,我的内在嵌入式代码运行速度比自动矢量化代码慢
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;
我相信我有一些如何在此代码中引入额外的循环,因此与自动矢量化代码相比它运行缓慢。与直接返回 128 位寄存器中比较值的 SIMD128 不同,SIMD512 返回掩码寄存器中的值,这增加了我的代码的复杂性。我在这里遗漏了什么吗,必须有一种方法可以直接比较和记录成功搜索的数量,而不是使用 XOR 操作等掩码。
最后,请建议我使用内在函数提高此代码性能的方法。我相信我可以使用内在函数来提高性能。至少对于 SIMD128 来说是这样,在使用内部函数时,我可以获得 25% 的性能。