【问题标题】:Sum all elements in a quadword vector in ARM assembly with NEON使用 NEON 在 ARM 汇编中对四字向量中的所有元素求和
【发布时间】:2011-08-03 18:17:05
【问题描述】:

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

【问题讨论】:

    标签: math assembly arm neon


    【解决方案1】:

    你可以试试这个(它不在 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的新手

    【讨论】:

    • 感谢我设法使用一个 VPADD 和两个 VADD 让它工作,我希望只需要使用 1 或 2 条指令,但我认为 3 只需要这样做。
    • 你能展示你的 ASM 吗?我认为它只需要一个 VADD 和一个 VPADD(至少从 C 代码来看)
    • 我想知道我们是否可以直接使用vaddvq_f32。它将直接跨向量执行加法
    【解决方案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 - 对性能至关重要。它大大提高了缓存命中率。

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

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

    【讨论】:

      【解决方案3】:

      这是 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;
      

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-08-21
        • 1970-01-01
        • 2016-04-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多