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的应用中,有所体现。

相关推荐
幼儿园老大*41 分钟前
走进 Go 语言基础语法
开发语言·后端·学习·golang·go
1 小时前
开源竞争-数据驱动成长-11/05-大专生的思考
人工智能·笔记·学习·算法·机器学习
ctrey_1 小时前
2024-11-4 学习人工智能的Day21 openCV(3)
人工智能·opencv·学习
啦啦右一1 小时前
前端 | MYTED单篇TED词汇学习功能优化
前端·学习
霍格沃兹测试开发学社测试人社区2 小时前
软件测试学习笔记丨Flask操作数据库-数据库和表的管理
软件测试·笔记·测试开发·学习·flask
今天我又学废了2 小时前
Scala学习记录,List
学习
王俊山IT2 小时前
C++学习笔记----10、模块、头文件及各种主题(一)---- 模块(5)
开发语言·c++·笔记·学习
Mephisto.java3 小时前
【大数据学习 | kafka高级部分】kafka中的选举机制
大数据·学习·kafka
羊小猪~~3 小时前
神经网络基础--什么是正向传播??什么是方向传播??
人工智能·pytorch·python·深度学习·神经网络·算法·机器学习
软工菜鸡4 小时前
预训练语言模型BERT——PaddleNLP中的预训练模型
大数据·人工智能·深度学习·算法·语言模型·自然语言处理·bert