gpt4 book ai didi

c - 按 1 个位置向左/向右打乱 AVX 256 vector 元素 - C 内在函数

转载 作者:太空狗 更新时间:2023-10-29 15:31:49 25 4
gpt4 key购买 nike

我试图找到一种更有效的方法来“旋转”或将 avx _m256 vector 中的 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] 数组并重构更有效。

-- 我还希望能够左右移动,因为我需要在其他地方执行类似的操作。

非常感谢任何帮助!谢谢!

最佳答案

对于 AVX2:

使用VPERMPS在一条交叉车道洗牌指令中完成。

rotated_right = _mm256_permutevar8x32_ps(src, _mm256_set_epi32(0,7,6,5,4,3,2,1));

对于 AVX(没有 AVX2)

既然你说数据已经来自内存,那么这可能很好:

  • 使用未对齐的负载将 7 个元素放到正确的位置,解决所有的车道交叉问题。
  • 然后将环绕的元素混合到其他 7 个 vector 中。
  • 要获得为混合就地包装的元素,可以使用广播加载将其放到高位置。 AVX 可以广播加载在一个VBROADCASTPS指令(因此 set1() 很便宜),尽管它确实需要 Intel SnB 和 IvB(仅有的两个具有 AVX 而不是 AVX2 的 Intel 微体系结构)上的随机端口。 (参见 标签 wiki 中的性能链接。

INSERTPS 仅适用于 XMM 目的地,无法到达上车道。

您可以使用 VINSERTF128 执行另一个未对齐的加载,最终将您想要的元素作为高元素放在上层 channel 中(在低层 channel 中有一些无关 vector )。

这可以编译,但未经测试。

__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
}

参见 the code + asm on Godbolt

关于c - 按 1 个位置向左/向右打乱 AVX 256 vector 元素 - C 内在函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40805099/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com