ARM架构NEON intrinsic函数学习笔记(四)

        实现一个点乘函数,实现两个向量的对应元素相乘最后相加的功能。

c语言代码(逐个元素进行计算)

float dot(const float *src01,const float *src02,const int len){
        float sum=0;
        for(int i=0;i<len;i++){
                sum+=src01[i]*src02[i];
        }

}

C语言代码(针对循环展开)

float dot_(const float *src01,const float *src02,const int len){
        float sum=0;
        int l=len-len%4;
        for(int i=0;i<l;i+=4){
                sum+=src01[i]*src02[i];
                sum+=src01[i+1]*src02[i+1];
                sum+=src01[i+2]*src02[i+2];
                sum+=src01[i+3]*src02[i+3];
        }
        for(int i=l;l<len;i++){
                sum+=src01[i]*src02[i];
        }
        return sum;
}

使用neon intrinsic函数

float dot__(const float *src01,const float *src02,const int len){
        float sum;
        float32x4_t sum_vec=vdupq_n_f32(0); //dup表示复制,即将0复制给4个float
        float32x4_t l_vec,r_vec;
        int l=len-len%4;   //满足整4个float的一起并行计算,比满足的需要逐个计算
        for(int i=0;i<l;i+=4){
                l_vec=vld1q_f32(src01+i);
                r_vec=vld1q_f32(src02+i);
                sum_vec=vmlaq_f32(sum_vec,l_vec,r_vec); //后两个向量对应元素相乘后与第一个向量对应元素相加
        }
        float32x2_t r=vadd_f32(vget_high_f32(sum_vec),vget_low_f32(sum_vec)); //取sum_vec高64位和低64位相加。vadd_f32是进行64位的加法,vaddq_f32才是进行128位的加法
        sum+=vget_lane_f32(vpadd_f32(r,r),0); //vpadd_f32是堆某个向量内的元素逐个相加,这里参数都是r,所以是对r寄存器内的两个float相加。vget_lane_f32用来获取指定索引的元素值

        for(int i=l;i<len;i++){
                sum+=src01[i]*src02[i];
        }
        return sum;
}

三种方法时间对比,在arm64v8-a架构上,点乘向量均是2<<20个float数据。

总结:

        vaddq_f32:实现128位,即包含4个float数据的寄存器之间的对应元素加法操作;

        vadd_f32:实现64位,即包含2个float数据的寄存器之间的对应元素加法操作;

        vpadd_f32:实现64位的,即包含2个float数据的寄存器的逐个元素相加;

        vmlaq_f32:实现128位的,即包含4个float数据的寄存器之间的对应元素的相乘,然后与第三个寄存器相加。mla=mul+add,方便记忆。

        vget_high_f32:获取寄存器的高64位包含的两个float数据,vget_low_f32同理;

        vget_lane_f32:获取寄存器指定索引的元素。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值