反向含有双打使用单个AVX本征a AVX寄存器(Reverse a AVX register con

2019-07-03 21:33发布

如果我有一个在他们4个双打的AVX寄存器,我想这个反向存放在另一个寄存器,是可以用一个单一的固有命令来做到这一点?

例如:如果我在SSE寄存器有4个浮筒,我可以使用:

_mm_shuffle_ps(A,A,_MM_SHUFFLE(0,1,2,3));

我能做到这一点使用,也许_mm256_permute2f128_pd() 我不认为你可以使用上述固有解决每个人的两倍。

Answer 1:

实际上,你需要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


Answer 2:

随着AVX2: VPERMPD ymm1, ymm2/m256, imm8具有相同的吞吐量和延迟其他车道交叉洗牌(如运行VPERM2F128上英特尔CPU)。 (在AMD挖掘机,如果这些号码是正确的 , vperm2f128是慢于单vpermpd )。

FMA是AVX2一个单独的功能位,但在实践中不存在具有FMA3但不AVX2任何的CPU。 (AMD推土机家族有4操作数FMA4)。 所以,你还是应该同时检查AVX2和FMA功能位,但你不必担心你的函数是在更少的CPU型号可用。


所以,如果你的代码已经依赖于FMA或AVX2,然后使用AVX2:

_mm256_permute4x64_pd(vec, _MM_SHUFFLE(0,1,2,3));  // i.e. 0b00011011

如果你已经不依赖于FMA或AVX2,只是AVX,这是不值得你的函数的另一个版本,只是在洗牌性能小的收获,然后用Mysticial的两指令的解决方案与SNB / IVB兼容性,以及AMD推土机家族预挖掘机。



文章来源: Reverse a AVX register containing doubles using a single AVX intrinsic