l从0开始学习NEON(2)

1、前言

继上一个例子,本次继续来学习NEON,本次学习NEON中向量拼接的操作,主要应用在图像的padding中。

https://blog.csdn.net/weixin_42108183/article/details/136440707

2、案例
2.1 案例1

在某些情况下,需要取在每个向量中去一部分值出来组成一个新的向量,这些值在逻辑上是连续的,如下图所示:

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <arm_neon.h>
#include <iostream>
#include <vector>
using namespace std;
#include <arm_neon.h>

int main(){
    // a拼接b 再取偏移量
    float _a[] = {1,2,3,4}, _b[] = {5,6,7,8} ;
    float32x4_t a = vld1q_f32(_a);
    float32x4_t b = vld1q_f32(_b);
    float32x4_t r1 = vextq_f32(a,b,1); //r1={2,3,4,5}
    
    vector<float> show_data(4);
    vst1q_f32 (show_data.data(),r1);  
    for(auto n : show_data){
        cout <<  static_cast<int>(n) << endl;
    }   
    cout << "----------" << endl;
    float32x4_t r2 = vextq_f32(a,b,2); //r2={3,4,5,6}
    vst1q_f32 (show_data.data(),r2);  
    for(auto n : show_data){
        cout <<  static_cast<int>(n) << endl;
    }   
    cout << "----------" << endl;

    float32x4_t r3 = vextq_f32(a,b,3); //r3={4,5,6,7}
    vst1q_f32 (show_data.data(),r3);  
    for(auto n : show_data){
        cout <<  static_cast<int>(n) << endl;
    }   
    // float32x4_t r4 = vextq_f32(a,b,4); // 错误 对vextq_f32偏移量的范围有限制,最多偏移一个q寄存器范围的值
    return 0;
}
2.2、案例2

​ 在padding时,如果使用传统的方法,直接在原数据的周围加一圈数据,再将新数据储存起来,再进行其他操作。如果在一行一行padding的同时进行其他操作,就可以不用申请额外的空间了。

  • 常量填充

    常量填充是指,实现定义一个固定的padding向量,每一行的数据,都利用这个padding向量来计算边界值,如下图时针对左边界的填充

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <arm_neon.h>
#include <iostream>
#include <vector>
using namespace std;
#include <arm_neon.h>

int main(){
    uint8_t pad_val = 0;
    //dup指令生成padding向量
    uint8x16_t v8_const_pad = vdupq_n_u8(pad_val);
  
    // 第0行数据
    vector<uint8_t> row0;
    for(int i=0;i<16;i++){
        row0.push_back(i);
    }

    auto v8_pre_row_data = v8_const_pad;  // 填充数据
    
    //读取第0行数据
    uint8x16_t v8_tmp_data = vld1q_u8(row0.data());
    //第0行带有左padding的数据
    uint8x16_t v8_row_cur_data = vextq_u8(v8_const_pad, v8_tmp_data, 15);  // 拼接起来从第15个偏移量的位置取数值
    

    // //读取第1行数据,假设第一行数据与第二行数据相等
    vector<uint8_t> row1 = row0
    v8_tmp_data = vld1q_u8(row1.data());
    // //第1行带有左padding的数据
    uint8x16_t v8_next_row_data = vextq_u8(v8_const_pad, v8_tmp_data, 15); 
    return 0;
}
  • 复制填充

    复制填充就是将填充值修改为图像最边界的值,基本上和常量填充一致。

  • 反射填充

    反射填充的解释就在复制填充的情况下,将paddding向量逆序,例如有一个向量为 abcdefgh ,对于普通反射,直接取值然后逆序即可abcdefgh -> cdba|abcdefgh| hgfe,而对于101反射,则需要再变化一点 ,abcdefgh -> ecdb|abcdefgh| gfed。普通反射和101反射的区别是对称中心两个a的中间还是a本身。代码如下:

    cpp 复制代码
    #include <stdio.h>
    #include <stdlib.h>
    #include <arm_neon.h>
    #include <iostream>
    #include <vector>
    using namespace std;
    
    #include <arm_neon.h>
    
    int main(){
        vector<uint8_t> row0;
        for(int i=0;i<16;i++){
            row0.push_back(i);
        }
    	// 取第1~7
        uint8x8_t v8_ref_pad0 = vld1_u8(row0.data()+1);  // 1,2,3,4,5,6,7,0
    	
        // 逆序
        uint8x8_t v8_ref_pad1 = vrev64_u8(v8_ref_pad0);  // 0,7,6,5,4,3,2,1
    		
        // 第0行原始数据
        uint8x16_t v8_row0_data = vld1q_u8(row0.data());   // 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
    	
        // 拼接,必须与第0行原始数据一样的长度才能调用vextq_u8这个函数
        uint8x16_t vcombine_0_1 = vcombine_u8(v8_ref_pad0, v8_ref_pad1);  // 1,2,3,4,5,6,7,0,0,7,6,5,4,3,2,1
        // 得到拼接后的向量
        uint8x16_t v8_cur_row_data = vextq_u8(vcombine_0_1, v8_row0_data, 15);  //  	           1,2,3,4,5,6,7,0,0,7,6,5,4,3,2,|1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14|,15
        return 0;
    }
3、总结

本文主要学习了NEON中向量拼接并取值的操作,并在图像padding的应用中,有所体现。

相关推荐
@小博的博客5 小时前
【Linux探索学习】第二篇Linux的基本指令(2)——开启Linux学习第二篇
linux·运维·学习
格林威7 小时前
常规线扫描镜头有哪些类型?能做什么?
人工智能·深度学习·数码相机·算法·计算机视觉·视觉检测·工业镜头
lyx33136967597 小时前
#深度学习基础:神经网络基础与PyTorch
pytorch·深度学习·神经网络·参数初始化
007php0077 小时前
某大厂跳动面试:计算机网络相关问题解析与总结
java·开发语言·学习·计算机网络·mysql·面试·职场和发展
知识分享小能手8 小时前
微信小程序入门学习教程,从入门到精通,微信小程序核心 API 详解与案例(13)
前端·javascript·学习·react.js·微信小程序·小程序·vue
递归不收敛8 小时前
吴恩达机器学习课程(PyTorch 适配)学习笔记:3.3 推荐系统全面解析
pytorch·学习·机器学习
B站计算机毕业设计之家8 小时前
智慧交通项目:Python+YOLOv8 实时交通标志系统 深度学习实战(TT100K+PySide6 源码+文档)✅
人工智能·python·深度学习·yolo·计算机视觉·智慧交通·交通标志
又是忙碌的一天10 小时前
前端学习 JavaScript(2)
前端·javascript·学习
蒙奇D索大10 小时前
【数据结构】考研数据结构核心考点:二叉排序树(BST)全方位详解与代码实现
数据结构·笔记·学习·考研·算法·改行学it
玲娜贝儿--努力学习买大鸡腿版10 小时前
推荐算法学习笔记(十九)阿里SIM 模型
笔记·学习·推荐算法