6

我对组装很陌生,虽然手臂信息中心通常很有帮助,但有时这些说明会让新手有点困惑。基本上我需要做的是在一个四字寄存器中对 4 个浮点值求和,并将结果存储在一个单精度寄存器中。我认为指令 VPADD 可以做我需要的,但我不太确定。

4

3 回答 3

4

你可以试试这个(它不在 ASM 中,但你应该能够轻松地转换它):

float32x2_t r = vadd_f32(vget_high_f32(m_type), vget_low_f32(m_type));
return vget_lane_f32(vpadd_f32(r, r), 0);

在 ASM 中,它可能只有 VADD 和 VPADD。

我不确定这是否只是一种方法(也是最佳方法),但我还没有想出/找到更好的方法......

PS。我也是NEON的新手

于 2011-08-03T20:13:38.900 回答
2

下面是 ASM 中的代码:

    vpadd.f32 d1,d6,d7    @ q3 is register that needs all of its contents summed          
    vadd.f32 s1,s2,s3     @ now we add the contents of d1 together (the sum)                
    vadd.f32 s0,s0,s1     @ sum += s1;

我可能忘了提到在 C 中的代码应该是这样的:

float sum = 1.0f;
sum += number1 * number2;

我已经省略了这段代码中的乘法。

于 2011-08-05T18:33:14.940 回答
2

似乎您想获得一定长度的数组的总和,而不仅仅是四个浮点值。

在这种情况下,您的代码将起作用,但远未优化:

  1. 许多许多管道联锁

  2. 每次迭代不必要的 32 位加法

假设数组的长度是 8 和至少 16 的倍数:

  vldmia {q0-q1}, [pSrc]!
  sub count, count, #8
loop:
  pld [pSrc, #32]
  vldmia {q3-q4}, [pSrc]!
  subs count, count, #8
  vadd.f32 q0, q0, q3
  vadd.f32 q1, q1, q4
  bgt loop

  vadd.f32 q0, q0, q1
  vpadd.f32 d0, d0, d1
  vadd.f32 s0, s0, s1
  • pld - 虽然是 ARM 指令而不是 NEON - 对性能至关重要。它大大提高了缓存命中率。

我希望上面的其余代码是不言自明的。

您会注意到此版本比您的初始版本快很多倍。

于 2011-11-01T06:21:12.783 回答