Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Math 使用NEON对ARM部件中四字向量中的所有元素求和_Math_Assembly_Arm_Neon - Fatal编程技术网

Math 使用NEON对ARM部件中四字向量中的所有元素求和

Math 使用NEON对ARM部件中四字向量中的所有元素求和,math,assembly,arm,neon,Math,Assembly,Arm,Neon,我对组装还比较陌生,虽然arm信息中心通常很有帮助,但有时对新手来说,说明可能有点混乱。基本上,我需要做的是将四字寄存器中的4个浮点值求和,并将结果存储在单个精度寄存器中。我认为VPADD指令可以满足我的需要,但我不太确定。您可以试试这个(它不在ASM中,但您应该能够轻松转换): 在ASM中,可能只有VADD和VPADD 我不确定这是否只是一种方法(也是最理想的),但我还没有找到更好的方法 另外,我对NEON也是新手以下是ASM中的代码: vpadd.f32 d1,d6,d7 @

我对组装还比较陌生,虽然arm信息中心通常很有帮助,但有时对新手来说,说明可能有点混乱。基本上,我需要做的是将四字寄存器中的4个浮点值求和,并将结果存储在单个精度寄存器中。我认为VPADD指令可以满足我的需要,但我不太确定。

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

在ASM中,可能只有VADD和VPADD

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


另外,我对NEON也是新手

以下是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;

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

似乎您想要得到数组某个长度的和,而不仅仅是四个浮点值

在这种情况下,您的代码可以工作,但远未优化:

  • 多管道联锁

  • 每次迭代不必要的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指令,而不是霓虹灯,对性能至关重要。它大大提高了缓存命中率
    我希望上面代码的其余部分是不言自明的


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

    谢谢,我使用了一个VPADD和两个VADD实现了此功能。我希望只需使用1或2个说明,但我认为3个就可以了。您可以展示您的ASM吗?我认为它只需要一个VADD和一个VPADD(至少从C代码看是这样)
      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