从0开始学习NEON(2)

1、前言

继上一个例子,本次继续来学习NEON,本次学习NEON中向量拼接的操作,主要应用在图像的padding中。
https://blog.csdn.net/weixin_42108183/article/details/136440707

2、案例
2.1 案例1

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

#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向量来计算边界值,如下图时针对左边界的填充

在这里插入图片描述

#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本身。代码如下:

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/433945.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

9.11一和零(LC474-M)

算法&#xff1a; 本题中strs 数组里的元素就是物品&#xff0c;每个物品都是一个&#xff01; 而m 和 n相当于是一个背包&#xff0c;两个维度的背包。 理解成多重背包的同学主要是把m和n混淆为物品了&#xff0c;感觉这是不同数量的物品&#xff0c;所以以为是多重背包。 …

IO之文件的打开操作和关闭

Linux下一切皆文件 一、文件的分类 学习链接&#xff1a;【精选】7种文件类型3种查看文件属性扩展名_七种文件类型-CSDN博客 二、对标准IO文件的相关操作 1、打开 &#xff08;1&#xff09;open--打开普通文件 如果需要别的权限&#xff0c;要使用 | 形式拼装 O_EXCL &…

HQYJ 2024-3-6 作业

创建一个伪终端 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <wait.h> void getstring(char *buf,int si…

【JavaWeb】Tomacat部署Web项目

Hi i,m JinXiang ⭐ 前言 ⭐ 本篇文章主要介绍【JavaWeb】Tomacat部署Web项目的详细使用以及部分理论知识 &#x1f349;欢迎点赞 &#x1f44d; 收藏 ⭐留言评论 &#x1f4dd;私信必回哟&#x1f601; &#x1f349;博主收将持续更新学习记录获&#xff0c;友友们有任何问题…

Linux系统之rename命令的基本使用

Linux系统之rename命令的基本使用 一、rename命令介绍二、raname工具版本2.1 C语言版本2.2 Perl版本 三、centos下的rename使用3.1 基本语法3.2 命令选项3.3 rename的基本使用 四、ubuntu下的rename使用4.1 基本语法4.2 命令选项4.3 rename命令的基本操作 五、rename注意事项 一…

双体系Java学习之全路线图

Java路线图 此路线图是为了我以后的Java学习指明方向。 希望大家都能在Java的路线上越走越远&#xff01;努力学习&#xff01;&#xff01;

javaSwing飞机大战

概述 1.1 项目简介 本次Java课程设计是做一个飞机大战的游戏&#xff0c;应用Swing编程&#xff0c;完成一个界面简洁流畅、游戏方式简单&#xff0c;玩起来易于上手的桌面游戏。该飞机大战项目运用的主要技术即是Swing编程中的一些窗口类库、事件监听以及贴图技术。 1.2 实…

coqui-ai/TTS 安装使用

Coqui AI的TTS是一款开源深度学习文本转语音工具&#xff0c;以高质量、多语言合成著称。它提供超过1100种语言的预训练模型库&#xff0c;能够轻松集成到各种应用中&#xff0c;并允许用户通过简单API进行个性化声音训练与微调。其技术亮点包括但不限于低资源适应性&#xff0…

golang中go build 后读取配置文件

golang打包后读取配置文件 在用go写代码的时候&#xff0c;为了好用经常使用go build 打包&#xff0c;如果我们用到了配置文件&#xff0c;就总是导致不能找到文件所在位置了出现bug&#xff0c;所以以下代码就解决了这个问题。 核心代码&#xff1a; file, err : exec.Look…

【C++ vscode 环境问题】vscode编译的时候:未定义标识符 thread mingw-w64安装支持c++11中thread

重新下载 MinGW64 https://sourceforge.net/projects/mingw-w64/files/mingw-w64/mingw-w64-release/往下滑动 最下面 找到这个版本下载解压并且记住下载的位置搜环境 添加你的MinGW64安装的位置 路径模仿我这样写 然后应用报存修改vscode配置文件 问题解决

【JSON2WEB】08 Amis的事件和校验

【JSON2WEB】01 WEB管理信息系统架构设计 【JSON2WEB】02 JSON2WEB初步UI设计 【JSON2WEB】03 go的模板包html/template的使用 【JSON2WEB】04 amis低代码前端框架介绍 【JSON2WEB】05 前端开发三件套 HTML CSS JavaScript 速成 【JSON2WEB】06 JSON2WEB前端框架搭建 【J…

Python(NetOps)前传-网络设备开局配置

背景 我们知道用Python在cli配置网络设备的前提是&#xff1a; 网络设备与Python主机网络可达网络设备已开启并完成ssh相关配置 目标 本文已华为S5720S-52P-LI-AC交换机为例&#xff0c;完成&#xff1a; 完成网络设备开局配置&#xff1b;用Python脚本验证ssh登录 配置 …

整流二极管:电路图、符号、功能与其它二极管的区别

整流二极管是 一种用于将交流电转换为直流电的半导体器件。二极管最重要的特性是单向导电性。在电路中&#xff0c;电流只能从二极管的正极流入&#xff0c;从负极流出。通常&#xff0c;它包含一个带有正极和负极端子的 PN 结。其结构如下图所示。 P区的载流子是空穴&#xf…

【Mysql】执行sql语句后,mysql都做了什么?

查数据大家都经常干&#xff0c;但是你知道从执行sql到看到结果&#xff0c;mysql背后都做了什么事情吗&#xff1f; 一、mysql的架构 client/server 这种客户端到服务端的架构&#xff0c;大家一定都很熟悉&#xff0c;其实 mysql 也与之类似。 可以有多个客户端与服务端连…

突破编程_前端_JS编程实例(简单树结构组件)

1 开发目标 实现如下简单树结构组件&#xff1a; 再点击树节点后&#xff0c;会调用客户端传入的回调函数&#xff1a; 2 详细需求 简单树结构组件需根据客户端提供的参数创建&#xff0c;具备动态构建树形结构节点、选项卡切换及自定义内容显示等功能&#xff1a; &#xf…

DR模式LVS负载均衡部署

实验&#xff1a;7-1做调度器&#xff1b;7-2和7-3做真实服务器&#xff1b;7-4做客户端&#xff1b; 1.先关闭所有的防火墙和selinux [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 [rootlocalhost ~]# 2.怎么看selinux状态 [rootlocalhost…

docker拉取镜像报错permission denied

ocker pull apache/causeway-app-helloworld:latest permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post “http://%2Fvar%2Frun%2Fdocker.sock/v1.24/images/create?fromImageapache%2Fcauseway-app-helloworld&a…

Vue:双token无感刷新

文章目录 初次授权与发放Token&#xff1a;Access Token的作用&#xff1a;Refresh Token的作用&#xff1a;无感刷新&#xff1a;安全机制&#xff1a;后端创建nest项目AppController 添加login、refresh、getinfo接口创建user.dto.tsAppController添加模拟数据 前端Hbuilder创…

node的使用和模块化认识

node使用 1. node运行文件 node执行js的方式是在cmd命令行运行运行方式两种 直接打开命令行输入node&#xff0c;进入node环境&#xff0c;书写javascript&#xff0c;这种方式书写javascript关闭命令行就需要在重新写一遍&#xff0c;一般开发不推荐使用这种方式。 退出node…

磁盘没有满 为什么提示磁盘空间不足?原来是inode惹的祸。

我为什么知道是inode 的问题呢&#xff1f; 接下备好瓜子花生来且听我分析 我一个免费开源根据ip获取用户地理位置的api 突然报错如下 failed to open stream: No space left on device in 然后登录linux 使用shell命令 自动补全功能竟然也提示磁盘空间不足 报错如下 cd /-b…