如果我有一个在他们4个双打的AVX寄存器,我想这个反向存放在另一个寄存器,是可以用一个单一的固有命令来做到这一点?
例如:如果我在SSE寄存器有4个浮筒,我可以使用:
_mm_shuffle_ps(A,A,_MM_SHUFFLE(0,1,2,3));
我能做到这一点使用,也许_mm256_permute2f128_pd()
我不认为你可以使用上述固有解决每个人的两倍。
如果我有一个在他们4个双打的AVX寄存器,我想这个反向存放在另一个寄存器,是可以用一个单一的固有命令来做到这一点?
例如:如果我在SSE寄存器有4个浮筒,我可以使用:
_mm_shuffle_ps(A,A,_MM_SHUFFLE(0,1,2,3));
我能做到这一点使用,也许_mm256_permute2f128_pd()
我不认为你可以使用上述固有解决每个人的两倍。
实际上,你需要2分的置换来做到这一点:
_mm256_permute2f128_pd()
只在128位的块的置换。 _mm256_permute_pd()
不横跨128位边界置换。 所以,你需要同时使用:
inline __m256d reverse(__m256d x){
x = _mm256_permute2f128_pd(x,x,1);
x = _mm256_permute_pd(x,5);
return x;
}
测试:
int main(){
__m256d x = _mm256_set_pd(13,12,11,10);
cout << x.m256d_f64[0] << " " << x.m256d_f64[1] << " " << x.m256d_f64[2] << " " << x.m256d_f64[3] << endl;
x = reverse(x);
cout << x.m256d_f64[0] << " " << x.m256d_f64[1] << " " << x.m256d_f64[2] << " " << x.m256d_f64[3] << endl;
}
输出:
10 11 12 13
13 12 11 10
随着AVX2: VPERMPD ymm1, ymm2/m256, imm8
具有相同的吞吐量和延迟其他车道交叉洗牌(如运行VPERM2F128
上英特尔CPU)。 (在AMD挖掘机,如果这些号码是正确的 , vperm2f128
是慢于单vpermpd
)。
FMA是AVX2一个单独的功能位,但在实践中不存在具有FMA3但不AVX2任何的CPU。 (AMD推土机家族有4操作数FMA4)。 所以,你还是应该同时检查AVX2和FMA功能位,但你不必担心你的函数是在更少的CPU型号可用。
_mm256_permute4x64_pd(vec, _MM_SHUFFLE(0,1,2,3)); // i.e. 0b00011011
如果你已经不依赖于FMA或AVX2,只是AVX,这是不值得你的函数的另一个版本,只是在洗牌性能小的收获,然后用Mysticial的两指令的解决方案与SNB / IVB兼容性,以及AMD推土机家族预挖掘机。