NEON SIMD 点积在 ARM Cortex A53 上速度不快

NEON SIMD dotproduct not faster on ARM Cortex A53

我正在尝试实现一个需要计算某些数组的点积的应用程序。这需要非常快,所以我考虑用 Neon 测试 SIMD。 我能够重写我的函数以使用 SIMD,但测量的时间与以前几乎相同,有时甚至更多。 没有 SIMD 需要 31 秒,有 SIMD 需要 32 秒。

这是我的 SIMD 代码:

        float output = 0.0;

    for (int i=0; i<NUMBER_OF_INPUTS; i+=4)
    {
        in1_126 = vld1q_f32(&source[i]);
        in2_126 = vld1q_f32(&weights[i]);
        out_126 = vmulq_f32(in1_126, in2_126);
        output +=  vaddvq_f32(out_126);
    }

    return output;  

这里没有:

    float output = 0.0;
    float tmp;



    for(unsigned int i = 0; i < NUMBER_OF_INPUTS; i++)
    {
        tmp = source[i] * weights[i];
        output += tmp;  
    }

    return output;  

我已经设置了那些编译器标志:

-mcpu=cortex-a53 -march=armv8-a+simd+crypto

但这并没有改变任何东西。

为什么时间上几乎没有差异?还是使用 NEON 使我的点积更快?您还有其他让它更快的想法吗?

感谢您的回复!

您不应该在循环中从向量寄存器移动到标量寄存器。

它会导致管道冲洗,每次发生大约需要 14 个周期。 (在 ARMv7-A

这些循环有多少取决于具体的架构。

你可以尝试什么:

out126 = vmovq_n_f32(0.0f);
for (int i=0; i<NUMBER_OF_INPUTS; i+=4)
{
  in1_126 = vld1q_f32(&source[i]);
  in2_126 = vld1q_f32(&weights[i]);
  out_126 = vmlaq_f32(out_126, in1_126, in2_126);
}

output =  vaddvq_f32(out_126);