【问题标题】:NEON SIMD dotproduct not faster on ARM Cortex A53ARM Cortex A53 上的 NEON SIMD 点积不更快
【发布时间】:2017-12-21 19:25:59
【问题描述】:

我正在尝试实现一个需要计算某些数组的点积的应用程序。这需要非常快,所以我考虑用 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 来加快我的 dotproduct 的速度是错误的?您还有其他想法可以让它更快吗?

感谢您的回复!

【问题讨论】:

  • 您是否检查过编译器是否已经在向量化标量代码?你也在使用-O3 吗?
  • 我不确定如何检查,但可能是这样。我没有使用 -O3 但现在我尝试使用它并给出相同的结果。
  • 使用objdump查看反汇编输出,或使用godbolt.org进行交互播放。

标签: arm simd neon dot-product


【解决方案1】:

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

它会导致管道刷新,并且每次发生大约需要 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);

【讨论】:

  • 谢谢!这解决了问题,现在我的程序运行时间大约为 18 秒。
  • @J.Ney 18 秒还不够好。您应该尝试更深入地展开以隐藏延迟。如果性能很关键,那么最终用汇编编写是唯一的选择。
猜你喜欢
  • 2021-12-11
  • 2013-02-20
  • 2017-08-02
  • 2013-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-25
  • 2011-05-05
相关资源
最近更新 更多