從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.pswp.cn/news/713931.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/713931.shtml
英文地址,請注明出處:http://en.pswp.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…