从0开始学习NEON(0)

1、前言

​ 最近在学习NEON指令集,主要学习"单指令流,多数据流"的编程方式,在这之前主要是针对cuda编程进行学习。最近的一部分工作转移到了arm主板上,接触到了 ncnn这个开源项目,不得不佩服nihui的强大。在学习ncnn的过程中了解到,arm下的模型加速主要用的技术就有NEON.因此,本着期待有一天能够熟读ncnn源码为目标,从0开始学习NEON!.

​ 关于NEON的介绍,这里不再赘述,网上有很多详细的文章,我是从下面这几篇文章入门的。

ARM SIMD 指令集:NEON 简介,CPU 优化技术-NEON 指令介绍,ARM NEON指令集总结, 本系列的文章主要是记录从0学习NEON中的一些知识点,便于往后复习,或者对刚学习NEON的同学有所帮助,如有不对的地方,还望指正。我的学习环境是一块国产主板,没有板子的同学可以使用NEON_2_SSE.h头文件在x86平台上进行仿真。

​ 由于本人是CV领域的,后面的学习都会在图像、深度学习部署方向进行,后续文章中还会汇总一些高质量的博客,便于参照学习,文章也许并不是循序渐进的,是在网上看到什么学习资料,就会耕畜相应的链接,并在本地进行学习或者复现。

2、学习记录
2.1、第一个例子
#include <stdio.h>
#include <stdlib.h>
// 包含NEON头文件
#include <arm_neon.h>
#include <math.h>int main(){unsigned char a[8] = {0,1,2,3,4,5,6,7};unsigned char b[8] = {8,9,10,11,12,13,14,15};unsigned char c[8];// uint8x8_t uint8类型的数据,连续读取8个数据,uint8x8_t rega, regb, regc;// 从内存中读取8个8位数据到寄存器, vld1q_u8则表示从内存中读取16个8位数据到内存中// 'q'指明操作寄存器宽度,为'q'时操作QWORD, 为128位,未指明时操作寄存器为DWORD,为64位;rega = vld1_u8(&a[0]);  regb = vld1_u8(&b[0]);// 向量加法,将两个寄存器中的值相加,使用一条指令就可以并行实现8个加法,体现了单指令多数据的思想。regc = vadd_u8(rega, regb);  // 将寄存器中的值写回到内存中vst1_u8(&c[0], regc);for(int i=0;i<8;i++){printf("%d ", c[i]);}return 0;
}

通过上面的例子,NEON的基本步骤和cuda是一样的,先将数据搬运到寄存器(显存),进行并行计算,最后再把结果写回到内存中。

2.2、第二个例子
#include <stdio.h>
#include <stdlib.h>
#include <arm_neon.h>
#include <math.h>
#include <iostream>
using namespace std;
int main(){// 1、直接在q寄存器中初始化4个类型为float的值。float32x4_t  arr = vdupq_n_f32(1.0);   //0初始化 arr = {1.0, 1.0, 1.0, 1.0}// 2、累加和float arr[4] = {1.0, 2.0, 3.0, 4.0};float32x4_t arr = vld1q_f32(arr);   // 将数据加载到寄存器float ans = vaddvq_f32(arr);        // ans = 1+2+3+4 = 10return 0;
}
2.3、第三个例子

第三个例子来自于https://blog.csdn.net/weixin_40162153/article/details/129109774?spm=1001.2014.3001.5502,

在opencv以RGB的格式读取一张图片时,其在内存中的排列为 RGBRGBRGB…,有时候,我们想把每个通道值单独提取出来进行直方图均衡化或者其他操作,在c++中,我们可以得到如下的代码。

void rgb_deinterleave_c(uint8_t *r, uint8_t *g, uint8_t *b, uint8_t *rgb, int len_color) {for (int i=0; i < len_color; i++) {r[i] = rgb[3*i];g[i] = rgb[3*i+1];b[i] = rgb[3*i+2];}
}

而通过NEON加速,可以通过如下的代码进行。

void rgb_deinterleave_neon(uint8_t *r, uint8_t *g, uint8_t *b, uint8_t *rgb, int len_color) {int num8x16 = len_color / 16;  //使用128位的q寄存器进行操作,需要操作的次数uint8x16x3_t intlv_rgb;  // 数据格式为 uint8类型的数据,16*3组。每次使用3个q寄存器.每个寄存器分别储存R、G、B值。for (int i=0; i < num8x16; i++) {// rgb+3*16*i  step,每处理一次需要往后+多少个位置,intlv_rgb = vld3q_u8(rgb+3*16*i);  // vld3q_u8,从起始点位置 交织加载 16个RGB数据vst1q_u8(r+16*i, intlv_rgb.val[0]); // 将16个R数据写回到内存vst1q_u8(g+16*i, intlv_rgb.val[1]); // 将16个G数据协回到内存vst1q_u8(b+16*i, intlv_rgb.val[2]); // 将16个B数据协回到内存}
3、总结

通过阅读几篇入门文章,初步了解了NEON的加速机制,主要是如何利用好d、q寄存器。使得加载和处理数据的时候后能够占满寄存器,。后续应该还会遇到向量化剩余部分(leftovers)处理进行学习。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C# 线性插值

线性插值是一种常用的插值算法&#xff0c;适用于许多实际场景。 传感器数据处理&#xff1a;在传感器数据处理中&#xff0c;可能会出现数据点不连续或不均匀的情况。使用线性插值可以根据已知的数据点来估算在两个数据点之间的数值&#xff0c;从而填补数据中的缺失或不连续之…

iOS消息转发流程

当向Objc对象发送消息时&#xff0c;如果找到对象对应的方法&#xff0c;就会进入消息转发流程&#xff0c;给开发者提供一些最后的机会处理消息无法发送问题&#xff0c;以免出现程序崩溃。 1. 回调对象的resolveInstanceMethod方法&#xff0c;在这个方法中&#xff0c;允许开…

阿里云定价_ECS产品价格_云服务器收费标准 - 阿里云官方活动

2024年最新阿里云服务器租用费用优惠价格表&#xff0c;轻量2核2G3M带宽轻量服务器一年61元&#xff0c;折合5元1个月&#xff0c;新老用户同享99元一年服务器&#xff0c;2核4G5M服务器ECS优惠价199元一年&#xff0c;2核4G4M轻量服务器165元一年&#xff0c;2核4G服务器30元3…

logo设计软件及网站汇总

文章目录 一、智能设计logo的网站二、常用的logo设计软件 一、智能设计logo的网站 Canva&#xff1a;Canva是一个在线设计平台&#xff0c;提供了丰富的模板和设计工具&#xff0c;可以帮助用户轻松设计出专业水平的logo。 DesignEvo&#xff1a;DesignEvo是一个专业的在线log…

基于 LLaMA 和 LangChain 实践本地 AI 知识库

有时候,我难免不由地感慨,真实的人类世界,本就是一个巨大的娱乐圈,即使是在英雄辈出的 IT 行业。数日前,Google 正式对外发布了 Gemini 1.5 Pro,一个建立在 Transformer 和 MoE 架构上的多模态模型。可惜,这个被 Google 寄予厚望的产品并未激起多少水花,因为就在同一天…

动作生成学习笔记

目录 ReMoDiffus 检索和扩散 文字生运动 action生运动 ReMoDiffus 检索和扩散 ICCV 2023 | 重塑人体动作生成,融合扩散模型与检索策略的新范式ReMoDiffuse来了,根据文本生成动作 有例子和模型&

CSS 显示隐藏动画(动画失效问题)

就像这个动画一样的效果&#xff0c;div 先是隐藏的&#xff0c;点击按钮后显示并且有动画效果&#xff0c;隐藏的时候同样。 <button class"btn" id"btn">点击</button><div class"box" id"box"></div><s…

一些常用到的git命令

git stash -a //缓存所有文件 git checkout -b dev origin/dev //切换到dev分支上,接着跟远程的origin地址上的dev分支关联起来 //推送本地分支到远程仓库 git push origin localbranchname:remotebrancname git revert onefile //https://www.freecodecamp.org/news/git-re…

S2---FPGA-A7板级原理图硬件实战

视频链接 FPGA-A7板级系统硬件实战01_哔哩哔哩_bilibili FPGA-A7板级原理图硬件实战 基于XC7A100TFGG484的FPGA硬件设计流程图 A7核心板&#xff0c;是基于XILINX公司的ARTIX-7系列100T的XC7A100T,2FGG484I这款芯片开发的高性能核心板&#xff0c;具有高速&#xff0c;高带宽&a…

HashMap在多线程下形成环的死锁详解

1. HashMap的工作原理 HashMap是Java中基于哈希表的Map接口的非同步实现。它存储键值对&#xff0c;并允许使用null键和null值。HashMap通过使用键对象的hashCode()方法来决定键值对的存储位置。 2. 多线程环境下的问题 在多线程环境下&#xff0c;如果多个线程同时对HashMap进…

Android 签名机制

V1是内部文件单个签 但是增加apk文件目录下面随意增加文件并不会有影响,它只关心meta-info文件 mf汇总清单的各个文件sha256 V2 整个APK文件,按文件进行hash 那么便不能随便在这里面增加文件了,增加了签名分块&#xff08;不然签名信息存哪里&#xff09;这里涉及一个文件概念 …

如何修炼成“神医”——《OceanBase诊断系列》之一

本系列是基于OcenaBase 开发工程师在工作中的一些诊断经验&#xff0c;也欢迎大家分享相关经验。 1. 关于神医的故事 扁鹊&#xff0c;中国古代第一个被正史记载的医生&#xff0c;他的成才之路非常传奇。年轻时&#xff0c;扁鹊是一家客栈的主管。有一位名叫长桑君的客人来到…

性能优化篇(二) 静态合批步骤与所有注意事项\游戏运行时使用代码启动静态合批

静态合批步骤: 1.开启Project Settings —>Player–>Other Setting里勾选Static Batching选项(一般情况下unity都是默认勾选状态) 2.勾选需要合批的静态物体上的Batching Static项,勾选后此物体下的所有子物体都默认参与静态合批(勾选后物体不能进行移动/旋转/缩放操作,…

02-设计概述

上一篇&#xff1a;01-导言 本章重点讨论 JNI 中的主要设计问题。本节中的大多数设计问题都与本地方法有关。调用 API 的设计将在第 5 章&#xff1a;调用 API 中介绍。 2.1 JNI 接口函数和指针 本地代码通过调用 JNI 函数来访问 Java 虚拟机功能。JNI 函数可通过接口指针使用…

LeetCode383. 赎金信(C++)

LeetCode383. 赎金信 题目链接代码 题目链接 https://leetcode.cn/problems/ransom-note/description/ 代码 class Solution { public:bool canConstruct(string ransomNote, string magazine) {int record[26] {0};if(ransomNote.size() > magazine.size()) return fa…

多层感知器(神经网络)与激活函数

单个神经元&#xff08;二分类&#xff09; 多个神经元&#xff08;多分类&#xff09; 多层感知器 多层感知器&#xff0c;他是一种深度学习模型&#xff0c;通过多层神经元的连接和激活来解决非线性问题。 激活函数 激活函数的种类包括relu&#xff0c;sigmoid和tanh等 …

批量检测微信小程序是否封禁接口源码

<?php // 要检测的 appid 列表 $appids array(appid1, appid2, appid3); // 使用实际的 appid // 循环调用接口检测小程序状态 foreach ($appids as $appid) { $url https://yan.changxunwangluo.cn/xcx/check_mini_program.php?appid . urlencode($appid); $…

敏捷开发模型:一种灵活、协作和持续的软件开发方法

敏捷开发模型&#xff1a;一种灵活、协作和持续的软件开发方法 引言 在软件开发领域&#xff0c;随着市场需求的不断变化和技术的迅速发展&#xff0c;传统的瀑布模型逐渐暴露出其局限性。为了应对这些挑战&#xff0c;敏捷开发模型应运而生。敏捷开发模型强调灵活、协作和持…

【ArcPy】简化ArcGISPro默认Python环境体量

参考文献 安装 ArcPy—ArcGIS Pro | 文档

找工作笔记

记录利用讯飞星火 问题1&#xff1a;作为一名无线通信工程师&#xff0c;找到适合自己的工作需要一系列的准备和策略。以下是一些建议&#xff0c;帮助你找到理想的职位&#xff1a; 1. **更新简历和在线资料**&#xff1a;---重要&#xff0c; - 确保你的简历是最新的&am…