使用NEON对ARM程序集中四字向量中的所有元素求和

时间:2011-08-03 18:17:06

标签: math assembly arm neon

我对装配很新,虽然手臂信息中心经常有用,但有时指令对新手来说有点混乱。基本上我需要做的是在四字寄存器中求和4个浮点值并将结果存储在单个精度寄存器中。我认为指令VPADD可以做我需要的但我不太确定。

3 个答案:

答案 0 :(得分: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的新手

答案 1 :(得分: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;

我已经省略了这个小块代码的乘法。

答案 2 :(得分:2)

似乎你想得到一定数量长度的总和,而不仅仅是四个浮点值。

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

  1. 许多管道联锁

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

  3. 假设数组的长度是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 - 对性能至关重要。它大大提高了缓存命中率。

    我希望上面的其余代码是自我解释的。

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