我对装配很新,虽然手臂信息中心经常有用,但有时指令对新手来说有点混乱。基本上我需要做的是在四字寄存器中求和4个浮点值并将结果存储在单个精度寄存器中。我认为指令VPADD可以做我需要的但我不太确定。
答案 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)
似乎你想得到一定数量长度的总和,而不仅仅是四个浮点值。
在这种情况下,您的代码将起作用,但远未优化:
许多管道联锁
每次迭代不必要的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
我希望上面的其余代码是自我解释的。
您会注意到此版本比初始版本快许多倍。