原始标量函数
static inline uint32 abc(uint32 bytes, int shift)
{
uint32 kMul= 0x1e35a7bd;
return (bytes * kMul) >> shift;
}
等效 AVX 功能
static inline uint32 abc(uint32 bytes, int shift)
{
uint32 kMul= 0x1e35a7bd;
__m256i a,b,c,resShift,shift_256i;
a=_mm256_set1_epi32(bytes);
b=_mm256_set1_epi32(kMul);
shift_256i=_mm256_set1_epi32(shift);
c=_mm256_mul_epi32(a,b);
resShift=_mm256_srlv_epi64(c,shift_256i);
// I am not sure what function to use to convert m256i variable into integer
}
我不确定如何在最后一步中将 m256i 变量转换为整数。 resShift 具有右移的 m256i 值,但我必须将其转换为整数形式并从该函数返回。有什么帮助吗?
最佳答案
您可以咨询Intel Intrinsics Guide 。您显然需要一些提取内在的内容,但我找不到任何可以一步完成的内容。以下是如何用两条指令完成此操作:
__m128i lower = _mm256_extracti128_si256(resShift, 0);
return _mm_extract_epi32(lower, 0);
但是请注意,您所做的事情完全没有意义。您不是为单个输入计算单个结果,而是重复此输入八次并解决八个相同的问题以获得八个相同的答案。因此,您不需要做任何事情就可以多做八倍的工作。此外,复制本身(set1_ 内在函数)将花费额外的时间。您的 AVX 例程不会比标量例程运行得更快。
附注顺便说一句,您应该使用 _mm256_srlv_epi32 而不是 _mm256_srlv_epi64 进行移位,因为您已在寄存器中打包了 32 位数据。
关于c++ - 我正在尝试使用 AVX2 重写函数并遇到问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31528494/