C++ 使用霓虹灯内部特性加速浮标的高斯模糊

C++ 使用霓虹灯内部特性加速浮标的高斯模糊,c++,image-processing,assembly,neon,gaussianblur,C++,Image Processing,Assembly,Neon,Gaussianblur,我想在arm中加速算法的某些部分(gaussianblur过滤器),我决定将SIMD与NEON Inquired一起使用。 但不幸的是,用NEON编写的代码比纯cpp代码要慢得多。 这些是纯cpp代码和NEON版本的代码。 有可能改进吗 纯cpp: inline void GaussianBlur_5x5_row(const float __restrict_arr *in, float __restrict_arr *out, const unsigned int cols) { //

我想在arm中加速算法的某些部分(gaussianblur过滤器),我决定将SIMDNEON Inquired一起使用。 但不幸的是,用NEON编写的代码比纯cpp代码要慢得多。 这些是纯cpp代码和NEON版本的代码。 有可能改进吗

纯cpp:

inline void GaussianBlur_5x5_row(const float __restrict_arr *in, float __restrict_arr *out, const unsigned int cols)
{
    //Left columns
    out[0] = (in[0]+in[2])*0.054488685f + (in[0]+in[1])*0.24420135f + in[0]*0.40261996f;
    out[1] = (in[0]+in[3])*0.054488685f + (in[0]+in[2])*0.24420135f + in[1]*0.40261996f;

    //Middle columns 
    for (unsigned int j=2; j<cols-2; j+=1)
    {
        out[j] = (in[j-2]+in[j+2])*0.054488685f + (in[j-1]+in[j+1])*0.24420135f + in[j]*0.40261996f;
        out[j+1] = (in[j-1]+in[j+3])*0.054488685f + (in[j]+in[j+2])*0.24420135f + in[j+1]*0.40261996f;


    }
    //Right columns
    out[cols-2] = (in[cols-4]+in[cols-1])*0.054488685f + (in[cols-3]+in[cols-1])*0.24420135f + in[cols-2]*0.40261996f;
    out[cols-1] = (in[cols-3]+in[cols-1])*0.054488685f + (in[cols-2]+in[cols-1])*0.24420135f + in[cols-1]*0.40261996f;
}
inline void GaussianBlur\u 5x5\u行(常量浮点限制到达,浮点限制到达,常量无符号整数列)
{
//左列
out[0]=(in[0]+in[2])*0.054488685f+(in[0]+in[1])*0.24420135f+in[0]*0.40261996f;
out[1]=(in[0]+in[3])*0.054488685f+(in[0]+in[2])*0.24420135f+in[1]*0.40261996f;
//中柱
对于(无符号整数j=2;j
出于软件工程和性能原因,这些应该是局部变量


当这些是全局变量时,生成的汇编代码中充斥着冗余的
vstr
指令。

(1)针对哪种特定的ARM体系结构?(2)正在使用哪个编译器,用于调用编译器的编译开关是什么?arm cortex a53是目标,对于使用gcc 8.3编译器和-o3 optimization Flag进行编译,我仍然无法获得要编译的代码。请在问题中添加完整的编译器命令行,以便其他人可以重现您的观察结果。foR编译这部分代码,你需要拥有所有的头文件,如果……可能的话,给我你的电子邮件地址,发送所有的,只是看看你的纯C++代码:“中间列”每个都计算了两次,这似乎相当浪费。循环是否应该说
j+=2
?那么像
coef_1
这样的常量也应该让编译器像处理字符串文本一样处理它们。非常量全局对常量来说也是可怕的,特别是当您在存储到未知
float*
的循环中读取它们时。
#include <arm_neon.h>

//kernels coefficients for sigma =1  and  kernel_size =5

float32x4_t coef_1 = { 0.054488685f , 0.122100675f , 0.20130998f , 0.122100675f };
float32x4_t coef_2 = { 0.122100675f , 0.20130998f  , 0.122100675f, 0.054488685f };

float32x4_t load_1 ,
            load_2 ,
            load_3 ,
            help_1 ,
            help_2 ,
            help_3 ;

float32x2_t a     ,
            dst_1 ,
            dst_2 ;

inline void GaussianBlur5x5_row_NEON_128bit_2_itr( const float __restrict_arr *in, float __restrict_arr *out, const unsigned int cols)
{
    //Left columns
    out[0] = (in[0]+in[2])*0.054488685f + (in[0]+in[1])*0.24420135f + in[0]*0.40261996f;
    out[1] = (in[0]+in[3])*0.054488685f + (in[0]+in[2])*0.24420135f + in[1]*0.40261996f;

    //Middle columns
    for (unsigned int j=2; j<cols-2; j+=2)
    {

     load_1 = vld1q_f32( &in[j-2] );
     load_2 = vld1q_f32( &in[j-1] );
     load_3 = vld1q_f32( &in[j  ] );

     help_1 = vmulq_f32( load_1 , coef_1 );
     help_2 = vmulq_f32( load_2 , coef_2 );
     help_3 = vaddq_f32( help_1 , help_2 );
     a      = vadd_f32 ( vget_high_f32( help_3 ) ,  vget_low_f32( help_3 ) );
     dst_1  = vpadd_f32( a , a );

     help_1 = vmulq_f32( load_2 , coef_1 );
     help_2 = vmulq_f32( load_3 , coef_2 );
     help_3 = vaddq_f32( help_1 , help_2 );
     a      = vadd_f32 ( vget_high_f32( help_3 ) ,  vget_low_f32( help_3 ) );
     dst_2  = vpadd_f32( a , a );

     out[j  ] = dst_1[0];
     out[j+1] = dst_2[0];
    }
    //Right columns
    out[cols-2] = (in[cols-4]+in[cols-1])*0.054488685f + (in[cols-3]+in[cols-1])*0.24420135f + in[cols-2]*0.40261996f;
    out[cols-1] = (in[cols-3]+in[cols-1])*0.054488685f + (in[cols-2]+in[cols-1])*0.24420135f + in[cols-1]*0.40261996f;
}
float32x4_t load_1 ,
            load_2 ,
            load_3 ,
            help_1 ,
            help_2 ,
            help_3 ;

float32x2_t a     ,
            dst_1 ,
            dst_2 ;