类似于 SIMD 指令的宏

Posted

技术标签:

【中文标题】类似于 SIMD 指令的宏【英文标题】:Macro similar to SIMD instruction 【发布时间】:2016-08-11 11:36:58 【问题描述】:

我正在尝试创建一些在某种程度上类似于 SIMD 内在函数的宏。我想要创建这些宏的原因是我正在使用一个名为“Gem5”的模拟器,它不支持 SIMD。

首先,我创建了一个结构,它定义了一个包含 4 个压缩单精度浮点元素的向量,如下所示:

  typedef struct
  
  float vec1;
  float vec2;
  float vec3;
  float vec4;
   __m128 __attribute__((aligned(16)));

然后我创建了 ADD 宏:

   #define __M128_MM_ADD_PS(dest, a,b)  \
                                      \
  (dest)->vec1 = (a)->vec1 + (b)->vec1; \
  (dest)->vec2 = (a)->vec2 + (b)->vec2; \
  (dest)->vec3 = (a)->vec3 + (b)->vec3; \
  (dest)->vec4 = (a)->vec4 + (b)->vec4; \
  

还有另一个用于将结果存储在浮点数组中的宏:

  #define __M128_MM_MOVA_PS(dest, a) \
   \
  dest[0] = a->vec1; \
  dest[1] = a->vec2; \
  dest[2] = a->vec3; \
  dest[3] = a->vec4; \
  

对他们来说,我已经将变量声明为 __m128 和一个浮点数组来存储结果,这样(一个小例子):

 void foo()
 __m128 bfly0_rv, x_n2_vec, x_N2_vec;
 float *x;

 __M128_MM_ADD_PS(bfly0_rv,x_n2_vec,x_N2_vec);
 __M128_MM_MOVA_PS(&x[n2],bfly0_rv);
 

我收到了这些错误消息:

对于 ADD 宏 错误:“->”的类型参数无效(有“__m128”) (dest)->vec4 = (a)->vec4 + (b)->vec4;

用于存储宏 错误:“->”的类型参数无效(有“__m128”) dest[3] = a->vec4;

任何人都可以对此有所了解吗?

【问题讨论】:

【参考方案1】:

您的所有宏都可以使用指向__m128 的指针,但您只传递__m128 而不是__m128 *。只需在宏内部将-> 替换为. 或在宏参数前添加&

__M128_MM_ADD_PS(&bfly0_rv, &x_n2_vec, &x_N2_vec);
__M128_MM_MOVA_PS(&x[n2], &bfly0_rv);

也不要忘记将desta 括在__M128_MM_MOVA_PS 的大括号中。

附:在宏定义中使用do ... while(0) 而不是 ... 会更好。

【讨论】:

所有错误都消失了,除了 Storing 宏它向我显示以下消息:错误:下标值既不是数组也不是指针也不是向量 dest[0] = a.vec1 它指向 dest[0]。 @A.nechi 你在dest 周围加了大括号吗?没有它们,它会扩展到&x[n2][0],这肯定不是你想要的。 你太棒了:)

以上是关于类似于 SIMD 指令的宏的主要内容,如果未能解决你的问题,请参考以下文章

MultiMedia eXtensions - MMX:第一套应用于英特尔 80x86 指令集的 SIMD 扩展

是否有用于元素部分移位的 simd 指令/内在/内置?

SSE3指令有啥功能?

OpenMP 为内联函数声明 SIMD

指令级并行与 SIMD

ARM NEON指令集总结