霓虹灯浮动乘法比预期慢

tom*_*mto 5 c++ gcc arm simd neon

我有两个浮标选项卡.我需要将第一个选项卡中的元素与第二个选项卡中的相应元素相乘,并将结果存储在第三个选项卡中.

我想使用NEON来并行化浮点乘法:同时进行四次浮点乘法而不是一次.

我预计会有显着的加速,但我的执行时间减少了大约20%.这是我的代码:

#include <stdlib.h>
#include <iostream>
#include <arm_neon.h>

const int n = 100; // table size

/* fill a tab with random floats */
void rand_tab(float *t) {
    for (int i = 0; i < n; i++)
        t[i] = (float)rand()/(float)RAND_MAX;
}

/* Multiply elements of two tabs and store results in third tab
 - STANDARD processing. */
void mul_tab_standard(float *t1, float *t2, float *tr) {
    for (int i = 0; i < n; i++)
         tr[i] = t1[i] * t2[i]; 
}

/* Multiply elements of two tabs and store results in third tab 
- NEON processing. */
void mul_tab_neon(float *t1, float *t2, float *tr) {
    for (int i = 0; i < n; i+=4)
        vst1q_f32(tr+i, vmulq_f32(vld1q_f32(t1+i), vld1q_f32(t2+i)));
}

int main() {
    float t1[n], t2[n], tr[n];

    /* fill tables with random values */
    srand(1); rand_tab(t1); rand_tab(t2);


    // I repeat table multiplication function 1000000 times for measuring purposes:
    for (int k=0; k < 1000000; k++)
        mul_tab_standard(t1, t2, tr);  // switch to next line for comparison:
    //mul_tab_neon(t1, t2, tr);  
    return 1;
}
Run Code Online (Sandbox Code Playgroud)

我运行以下命令进行编译:g ++ -mfpu = neon -ffast-math neon_test.cpp

我的CPU:ARMv7处理器rev 0(v7l)

您对我如何实现更显着的加速有任何想法吗?

Mar*_*han 5

Cortex-A8和Cortex-A9每个周期只能进行两次SP FP乘法运算,因此最多可以将这些(最常用)CPU的性能提高一倍.实际上,ARM CPU的IPC非常低,因此最好尽可能地展开循环.如果你想要最终性能,请写入汇编:gcc的ARM代码生成器无法与x86一样好.

我还建议使用特定于CPU的优化选项:Cortex-A9的"-O3 -mcpu = cortex-a9 -march = armv7-a -mtune = cortex-a9 -mfpu = neon -mthumb"; 对于Cortex-A15,Cortex-A8和Cortex-A5相应地替换-mcpu = -mtune = cortex-a15/a8/a5.gcc没有针对Qualcomm CPU的优化,因此对于Qualcomm Scorpion使用Cortex-A8参数(并且还会比平常更多地展开),而对于Qualcomm Krait尝试Cortex-A15参数(您将需要最新版本的gcc支持它).