【问题标题】:How to rotate an SSE/AVX vector如何旋转 SSE/AVX 矢量
【发布时间】:2012-08-08 01:25:59
【问题描述】:

我需要以尽可能少的时钟周期执行旋转操作。 在第一种情况下,我们假设 __m128i 作为源和目标类型:

来源:|| A0 || A1 || A2 || A3 ||
 目标:|| A1 || A2 || A3 || A0 ||
dest = (__m128i)_mm_shuffle_epi32((__m128i)source, _MM_SHUFFLE(0,3,2,1));

现在我想对 AVX 内在函数做同样的事情。 所以让我们假设这次__m256i 作为源和目标类型:

来源:|| A0 || A1 || A2 || A3 || A4 || A5 || A6 || A7 ||
 目标:|| A1 || A2 || A3 || A4 || A5 || A6 || A7 || A0 ||

AVX 内在函数缺少大部分相应的 SSE 整数运算。 也许有一些方法可以使用浮点版本获得所需的输出。

我试过了:

dest = (__m256i)_mm256_shuffle_ps((__m256)source, (__m256)source, _MM_SHUFFLE(0,3,2,1));

但我得到的是:

|| A0 || A2 || A3 || A4 || A5 || A6 || A7 || A1 ||

关于如何以有效方式解决此问题的任何想法? (没有混合 SSE 和 AVX 操作,也没有“手动”反转 A0A1

提前致谢!

【问题讨论】:

  • 对SSE和AVX没有太多经验,但是在第二行代码中,如果dest类型是__m256,为什么要转换成__m128i
  • 当然是__m256i,谢谢!
  • 不,我只是剪切和粘贴出错了..
  • 似乎所有有用的指令都在 AVX2 中(他们为什么不发布那个first?)

标签: c x86 sse intrinsics avx


【解决方案1】:

我的解决方案:

__m256 tmp =  ( __m256 ) _mm256_permute_ps((__m256)_source, _MM_SHUFFLE ( 0,3,2,1 ));
* ( _dest ) =  ( __m256i) _mm256_blend_ps(tmp, _mm256_permute2f128_ps ( tmp,tmp,1 ), 136);  

【讨论】:

  • 有没有机会解释一下你在第二行的传递? (1 和 136)我已阅读文档,但仍然不明白为什么这些特定值是您想要的。
  • @OrvidKing:permute2f128(tmp,tmp,1) 交换上下 128b 通道。 136 = 0x88 = 从一个向量中获取高元素,从另一个向量中获取其他元素(因此,每个通道中的 0x8,因为 blendps 使用两个通道的 imm8 的两半。)
【解决方案2】:

我还没有检查过 AVX 的情况,但至少对于 SSE,您是否考虑过 _mm_align*

例如,这会将字节向量旋转 2 个字节:

__m128i v;
v = _mm_alignr_epi8 (v, v, 2) // v = v[2,3,4,5,6,7,8,9,10,11,12,13,14,15,0,1]

这可以是一条指令。此类操作也是 lat 1 / tp 1,即快速。

AVX 使用这种方法可能有点麻烦,因此调整可能没有用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-31
    • 2017-06-10
    • 1970-01-01
    • 1970-01-01
    • 2012-10-22
    • 1970-01-01
    • 1970-01-01
    • 2015-10-11
    相关资源
    最近更新 更多