【问题标题】:How can I reorder a 128 bit vector using Intel intrinsics?如何使用英特尔内在函数重新排序 128 位向量?
【发布时间】:2017-06-25 14:37:13
【问题描述】:

我有一个 4 个浮点数的 128 位向量已经计算出来,我想像这样改变这个向量的顺序:

Vector A before reordering
+---+---+---+---+
| a | b | c | d |
+---+---+---+---+

Vector A after reordering
+---+---+---+---+
| b | a | c | d |
+---+---+---+---+

正如我所说的,向量是通过早期计算计算出来的,所以无法使用_mm_set_ps()...有人知道如何完成吗?

【问题讨论】:

  • 用 gcc 或 clang 编译 __m128 f(__m128 x){return _mm_setr_ps(x[1],x[0],x[2],x[3]);}-O3 -msse4 产生 shufps $225, %xmm0, %xmm0,看起来像是一个强烈的提示......
  • 查看software.intel.com/sites/landingpage/IntrinsicsGuide 以获得方便的搜索工具,以及sse tag wikix86 tag wiki 中的其他链接。如果你发现你的代码有太多的洗牌,看看重新排列你的数据结构,或者你如何向量化一个嵌套循环,尽可能减少洗牌的数量。

标签: c x86 sse simd intrinsics


【解决方案1】:

您正在寻找 SHUFPS instruction(随机压缩单精度浮点数)。
对应的内在函数是_mm_shuffle_ps

__m128 _mm_shuffle_ps(__m128 a, __m128 b, unsigned int imm8);

第三个参数,一个 8 位立即数,是排列。这表明您希望如何对值进行混洗。要以可读的方式创建它,您需要使用 _MM_SHUFFLE 宏。这是_MM_SHUFFLE 工作原理的有用图形描述,取自some old Microsoft documentation

【讨论】:

  • 当目标 xmm 寄存器与第一个源 xmm 寄存器 (m3 == m1) 相同时,编译器是否会识别,以便它执行就地洗牌(使用单个 SHUFPS 指令)而不是使用临时 xmm 寄存器?
  • 我一般会跳过_MM_SHUFFLE,把它写成base 4,然后转换成base 16。base 4中的1032变成(1*4+0)*1​​6 + (3*4+2) = 0x4E。
  • 为什么反对_MM_SHUFFLE、@Zboson?我不明白 0x4E 怎么会比 _MM_SHUFFLE(1,0,3,2) 更清晰。
猜你喜欢
  • 1970-01-01
  • 2014-04-07
  • 2019-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-03
相关资源
最近更新 更多