【问题标题】:Neon intrinsics with complex numbers具有复数的霓虹内在函数
【发布时间】:2014-02-18 23:16:34
【问题描述】:

我有很多复数计算(通常是一个数组,其中包含一个由两个浮点数组成的结构来表示 im 和 re;见下文),并希望使用 NEON C 内在函数加速它们。如果你能给我一个例子来说明如何加速这样的事情,那就太棒了:

for(n = 0;n < 1024;n++,p++,ptemp++){  // get cir_abs, also find the biggest point (value and location).
    abs_squared = (Uns32)(((Int32)(p->re)) * ((Int32)(p->re)) 
                  + ((Int32)(p->im)) * ((Int32)(p->im)));
    // ...
}

p 是一个这样的数组:

typedef struct {
    Int16 re;
    Int16 im;
} Complex;

我已经阅读了“ARM C 语言扩展”的第 12 章,但仍然无法理解如何在此处加载和存储我的构造类型以对其进行计算。

【问题讨论】:

标签: c gcc arm neon


【解决方案1】:

使用vld2*内在函数在加载时将reim拆分到不同的寄存器中,然后分别处理它们,例如

Complex array[16];

const int16x8x2_t vec_complex = vld2q_s16((const int16_t*)array);
const int16x8_t vec_re = vec_complex.val[0];
const int16x8_t vec_im = vec_complex.val[1];
const int16x8_t vec_abssq = vmlaq_s16(vmulq_s16(vec_re, vec_re), vec_im, vec_im);

对于上面的代码clang 3.3生成

vld2.16 {d18, d19, d20, d21}, [r0]
vmul.i16 q8, q10, q10
vmla.i16 q8, q9, q9

【讨论】:

  • 谢谢,好像是我要找的东西。但是我会产生溢出,不是吗?所以我可能会用 int32x4 类型做所有事情。
  • 您可以类似地访问 int16x8_t 的部分 int16x4_t 并使用 vaddl_s16/vmull_s16/vmlal_s16 生成 4 个 32 位结果 int32x4_t(请注意,此操作输入 64位 SIMD 寄存器并输出 128 位 SIMD 寄存器)。
  • 例如const int32x4_t vec_abssq_lo = vmlal_s16(vmull_s16(vget_low_s16(vec_re), vget_low_s16(vec_re)), vget_low_s16(vec_im), vget_low_s16(vec_im));
  • 不幸的是,带有 NEON 内在函数的循环比“unNEONified”循环花费的时间更长。商店操作是最耗时的。没有商店的循环需要 0,39 我们和商店 12,4 我们......有没有可能改进这个?
  • 展开以隐藏延迟。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-08
  • 1970-01-01
  • 1970-01-01
  • 2016-11-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多