我试图找到一种更有效的方式来旋转"或者将avx _m256向量中的32位浮点值向右或向左移动一个位置。
这样:
a7,a6,a5,a4,a3,a2,a1,a0
变为
0,a7,a6,a5,a4,a3,a2,a1
(我不介意,无论如何,当我更换电池时数据会丢失。)
我已经看过这个帖子:Emulating shifts on 32 bytes with AVX 但我真的不明白发生了什么,也没有解释_MM_SHUFFLE(0,0,3,0)作为输入参数的作用。
我正在尝试优化此代码:
_mm256_store_ps(temp, array[POS(ii, jj)]);
_mm256_store_ps(left, array[POS(ii, jj-1)]);
tmp_array[POS(ii, jj)] = _mm256_set_ps(left[0], temp[7], temp[6], temp[5], temp[4], temp[3], temp[2], temp[1]);
我知道一旦轮班到位,我可以使用插入来替换剩余的单元格。我觉得这将更有效,然后解压缩到float [8]数组并重构。
- 我也希望能够左右移动,因为我需要在其他地方执行类似的操作。
非常感谢任何帮助!谢谢!
答案 0 :(得分:4)
对于AVX2 :
使用VPERMPS在一个交叉的随机播放指令中执行此操作。
rotated_right = _mm256_permutevar8x32_ps(src, _mm256_set_epi32(0,7,6,5,4,3,2,1));
对于AVX(不含AVX2)
由于你说数据来自内存,这可能是好的:
set1()
便宜),虽然它确实需要Intel SnB和IvB上的shuffle端口(只有两个Intel微架构与AVX但不是AVX2)。 (请参阅x86标记wiki中的perf链接。INSERTPS仅适用于XMM目的地,无法到达上层车道。
您可以使用VINSERTF128进行另一个未对齐的加载,最终将您想要的元素作为高级元素放在上部通道中(在低通道中有一些“不关心”矢量)。
这是编译,但未经过测试。
__m256 load_rotr(float *src)
{
#ifdef __AVX2__
__m256 orig = _mm256_loadu_ps(src);
__m256 rotated_right = _mm256_permutevar8x32_ps(orig, _mm256_set_epi32(0,7,6,5,4,3,2,1));
return rotated_right;
#else
__m256 shifted = _mm256_loadu_ps(src + 1);
__m256 bcast = _mm256_set1_ps(*src);
return _mm256_blend_ps(shifted, bcast, 0b10000000);
#endif
}