我正在尝试使用 AVX2 和 运行 将函数重写为问题
I am trying to rewrite a function using AVX2 and running into issues
原始标量函数
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 值,但我必须将其转换为整数形式并从该函数转换为 return。有帮助吗?
可以咨询Intel Intrinsics Guide。您显然需要一些 extract 内在函数,但我找不到任何可以一步完成的函数。以下是如何通过两条指令进行操作:
__m128i lower = _mm256_extracti128_si256(resShift, 0);
return _mm_extract_epi32(lower, 0);
但是请注意,您所做的事情完全没有意义。您无需为单个输入计算单个结果,而是将此输入重复八次并解决八个相同的问题以获得八个相同的答案。所以你在没有任何需要的情况下多做八倍的工作。此外,复制本身(set1_ 内在函数)将花费额外的时间。您的 AVX 例程不会比标量例程运行得更快。
P.S。顺便说一句,你应该使用 _mm256_srlv_epi32 而不是 _mm256_srlv_epi64 进行移位,因为你已经打包了 32 位数据在你的寄存器中。
原始标量函数
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 值,但我必须将其转换为整数形式并从该函数转换为 return。有帮助吗?
可以咨询Intel Intrinsics Guide。您显然需要一些 extract 内在函数,但我找不到任何可以一步完成的函数。以下是如何通过两条指令进行操作:
__m128i lower = _mm256_extracti128_si256(resShift, 0);
return _mm_extract_epi32(lower, 0);
但是请注意,您所做的事情完全没有意义。您无需为单个输入计算单个结果,而是将此输入重复八次并解决八个相同的问题以获得八个相同的答案。所以你在没有任何需要的情况下多做八倍的工作。此外,复制本身(set1_ 内在函数)将花费额外的时间。您的 AVX 例程不会比标量例程运行得更快。
P.S。顺便说一句,你应该使用 _mm256_srlv_epi32 而不是 _mm256_srlv_epi64 进行移位,因为你已经打包了 32 位数据在你的寄存器中。