C 使用单个AVX内在函数反转包含双精度的AVX寄存器

C 使用单个AVX内在函数反转包含双精度的AVX寄存器,c,sse,vectorization,simd,avx,C,Sse,Vectorization,Simd,Avx,如果我有一个包含4个双精度的AVX寄存器,并且我想在另一个寄存器中存储该寄存器的相反值,那么是否可以使用一个内部命令来实现这一点 例如:如果我在SSE寄存器中有4个浮点数,我可以使用: _mm_shuffle_ps(A,A,_MM_SHUFFLE(0,1,2,3)); 我是否可以使用\u mm256\u permute2f128\u pd()执行此操作?我不认为您可以使用上述内在函数来解决每个双精度问题。您实际上需要两个permutes来实现这一点: \u mm256\u permute2f

如果我有一个包含4个双精度的AVX寄存器,并且我想在另一个寄存器中存储该寄存器的相反值,那么是否可以使用一个内部命令来实现这一点

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

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

我是否可以使用
\u mm256\u permute2f128\u pd()
执行此操作?我不认为您可以使用上述内在函数来解决每个双精度问题。

您实际上需要两个permutes来实现这一点:

  • \u mm256\u permute2f128\u pd()
    仅在128位块中进行排列
  • \u mm256\u permute\u pd()
    不跨128位边界进行排列
因此,您需要同时使用这两种方法:

inline __m256d reverse(__m256d x){
    x = _mm256_permute2f128_pd(x,x,1);
    x = _mm256_permute_pd(x,5);
    return x;
}
测试:


AVX2新增了对粒度更细128位的车道交叉混洗的支持:

_mm256_permute4x64_pd(vec, _MM_SHUFFLE(0,1,2,3));  // i.e. 0b00011011
VPERMPD-ymm1、ymm2/m256、imm8
运行时的吞吐量和延迟与英特尔CPU上的其他车道交叉洗牌(如
VPERM2F128
)相同。(在AMD和Zen1()上,
vpermpd
比2-input
vperm2f128
快,因为它们处理256位向量)



有一些CPU使用FMA3而不是AVX2,例如AMD Piledriver和Steamroller。在英特尔,AVX2和FMA都是Haswell的新产品。AMD推土机系列已经过时,但仍然存在于家用电脑中,因此,即使您的功能利用了AVX1+FMA,您也可以选择也需要AVX2,让这些少数CPU退回到更糟糕的状态(例如,没有FMA的AVX1),或者制作另一个版本的功能。

Yep。值得记住的是,AVX2将添加一个完整的排列,即使您现在无法使用它,
VPERMPD
/
\u mm256\u permute4x64\u pd
。英特尔的参考文件有更多的细节。你知道这两条指令的延迟是如何比较的吗?我指的是“_mm_shuffle_ps()”反转SSE寄存器的延迟,以及上述AVX上的反转操作的延迟register@user1715122我不知道。你也许可以从中加起来。当然,由于其他因素,实际表现会更加复杂。
10  11  12  13
13  12  11  10
_mm256_permute4x64_pd(vec, _MM_SHUFFLE(0,1,2,3));  // i.e. 0b00011011