NEON 指令集基礎備忘】

      網(wǎng)友投稿 1422 2022-05-30

      轉自?http://blog.sina.com.cn/s/blog_602f87700102wj5w.html

      其他優(yōu)秀鏈接:https://blog.csdn.net/hemmingway/article/details/44832013

      之前在一些ARM CPU下,曾在編譯時指定過Neon。

      0. Neon簡介:

      0.1: 簡介:

      ARM Advanced SIMD延伸集,(ARM Cortex-A系列處理器的128位SIMD架構擴展)稱為NEON技術,它是一個結合64bit和128bit的SIMD(Single Instruction Multiple Data單指令多數(shù)據(jù))指令集。其針對多媒體和訊號處理程式具備標準化加速的能力,NEON具有一組廣泛的指令集、各自的寄存器陣列,以及獨立執(zhí)行的硬件。ARM NEON技術可加速多媒體和信號處理算法(如視頻編碼/解碼、2D/3D圖形、游戲、音頻和語音處理、圖像處理技術、電話和聲音合成)。

      NEON的寄存器:有16個128位四字寄存器Q0-Q15,32個64位雙字寄存器D0-D31,兩個寄存器是重疊的,在使用的時候需要特別注意,不小心就會被覆蓋掉。

      0.2: SIMD:

      通常我們進行多媒體處理的時候,很多的數(shù)據(jù)都是16位或者8位的,如果這些程序運行在32位的機器上,那么計算機有一部分的計算單元是沒有工作的.所以這是一種浪費.為了更好的使用那些被浪費的資源.SIMD就應運而生了.SIMD這種技術就是使用一條指令,但對多個相同類型和尺寸的數(shù)據(jù)進行并行處理.就像我們現(xiàn)實生活中的好幾個人都在做同一件事情那樣,這樣就可以將速度提升很多倍

      0.3:使用Neon的方式:

      按Sam的理解,使用Neon的方式有以下幾種:

      A:使用C的neon內聯(lián)函數(shù)。

      B:直接使用Neon匯編指令。

      C:使用某些第三方庫如OpenMAX.

      各自的優(yōu)缺點:

      A:使用Neon?intrinsics函數(shù),可以在直接接觸ASM的情況下,使用Neon。這些函數(shù)被定義在:

      arm_neon.h 中。

      類似于:

      NEON 指令集【基礎備忘】

      vadd_s8 (int8x8_t __a, int8x8_t __b)

      此方法需要注意2點:

      1.必須: #include

      2.編譯時必須加入; -mfloat-abi=softfp -mfpu=neon

      B:使用匯編指令:

      效率最高.?使用intrinsics沒法控制寄存器分配和內存對齊等。

      1.SIMD寄存器基本知識:

      SIMD寄存器共有16個128位的向量寄存器構成。而32個雙精度浮點寄存器共享了這16個寄存器;32個單精度浮點寄存器共享了前8個寄存器。因此,這寄存器組是與浮點寄存器共享的.

      單精度寄存器用s0~s31表示;(32bit)

      雙精度寄存器用d0~d31來表示;(64bit)

      而128位的SIMD寄存器則用q0~q15來表示.(128bit)

      2. Neon的數(shù)據(jù)從內存向寄存器加載(vld)和從寄存器向內存存儲(vst):

      如何靈活有效的加載和存儲數(shù)據(jù),對SIMD來說非常重要。先舉一下例子:

      24-bit的RGB圖像,像素在內存里的組織方式是R, G, B, R, G, B...,如果你想做一個簡單的圖像處理,比如把R和B通道互換,你該如何高效的使用NEON協(xié)處理器呢?

      首先想到的辦法是:從存儲空間線性加載RGB數(shù)據(jù)到D寄存器(64位雙精度寄存器),然后交換R和B數(shù)據(jù)。 但是這種線性加載的數(shù)據(jù)進行R和B通道的數(shù)據(jù)交換非常麻煩,需要首先掩碼mask,然后移位并合并掩碼數(shù)據(jù)。這種復雜的運算顯然并不高效。如圖所示:

      從r0內存處,開始讀取數(shù)據(jù)到寄存器。

      D0,D1,D2這三個64bit寄存器中各放置了雜亂的8個色數(shù)據(jù)。這樣非常不利于快速計算。

      NEON提供了各種結構的加載和存儲指令來處理這種情況,這些指令能把數(shù)據(jù)從存儲區(qū)加載的同時還能把這些值分開存儲到不同的寄存器中。

      從r0內存處開始讀取數(shù)據(jù)。

      然后使用VLD3分開加載的數(shù)據(jù)就能方便的使用指令(VSWP d0, d2)來進行R和B通道的交換了。

      然后把結果再寫入內存,當然也要使用interleave交織模式的存儲,即VST3存儲指令。

      3.?結構化加載和存儲語法和具體指令:

      NEON結構化加載會讀取內存內容到64-bit的NEON寄存器,使用可選的deinterleave選項,同樣加載指令也可以采用這種reinterleave的方式把寄存器的內容寫到內存空間。

      NEON存儲和加載的結構化方式,語法包括如下5個部分:

      加載VLD或者存儲VST指令助記符:instruction mnemonic

      一個表示interleave模式的數(shù)字,表示每個結構體元素間的間隔:interleave pattern

      表示每次訪問單元的位寬比特數(shù),即結構體內元素類型:element type

      讀寫的64-bit的NEON寄存器集合,最多可以列出4個寄存器,取決于interleave模式:NEON registers

      表示內存訪問地址的ARM寄存器,該地址可以在每次訪問時更新: ARM?address register

      交織模式:Interleave Pattern:

      加載和存儲指令可以用從1到4個相同大小的元素的交織結構體,這些元素可以是NEON指令通常支持的8,16或者32比特。

      VLD1是最簡單的形式,從內存加載1~4個寄存器的數(shù)據(jù),沒有deinterleave,即線性加載;

      VLD2加載2或者4個寄存器的數(shù)據(jù),解交織奇偶元素到各自的寄存器,這樣很容易的把交織的立體聲音頻數(shù)據(jù)分解為左右聲道的數(shù)據(jù);

      VLD3加載3個寄存器的數(shù)據(jù),很方便的把RGB的數(shù)據(jù)分為R、G、B通道;

      VLD4加載4個寄存器的數(shù)據(jù),解交織,用于分解ARGB圖像數(shù)據(jù);

      存儲和加載類似,只是把寄存器的數(shù)據(jù)interleave然后寫到內存。

      元素類型?Element Types

      加載和存儲interleave的數(shù)據(jù)的基本元素可以為8,16或者32比特的數(shù)據(jù)。比如NEON指令VLD2.16 {d0, d1}將加載4個16-bit元素到第一個寄存器,然后4個16-bit元素到第二個寄存器,把臨近的奇偶對分開保存到每個寄存器。

      把元素大小變成32-bits還是加載相同大小的數(shù)據(jù),但是只有2個元素來構成一個向量,同樣分成奇偶元素部分。

      4. 關于優(yōu)化的幾個例子:

      // C version

      void add_int_c(int* dst, int* src1, int* src2, int count)

      {

      int i;

      for (i = 0; i < count; i++)

      {

      dst[i] = src1[i] + src2[i];

      }

      }

      // NEON version

      void add_float_neon1(int* dst, int* src1, int* src2, int count)

      {

      int i;

      for (i = 0; i < count; i += 4)

      {

      int32x4_t in1, in2, out;

      in1 = vld1q_s32(src1);

      src1 += 4;

      in2 = vld1q_s32(src2);

      src2 += 4;

      out = vaddq_s32(in1, in2);

      vst1q_s32(dst, out);

      dst += 4;

      }

      }

      其中 vld1q_s32(src1):

      被解析為:?vld1.32 {d0, d1}, [r0]

      vld: load數(shù)據(jù)到寄存器。 1:表示依次讀取。32:每份數(shù)據(jù)32bit. ?d0, d1,兩個64bit寄存器。所以,表示要讀4份數(shù)據(jù)。 ?r0:從r0內存處開始讀。

      單片機 匯編語言

      版權聲明:本文內容由網(wǎng)絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內刪除侵權內容。

      上一篇:詳解高級PHP工程師面試題
      下一篇:Linux查看用戶及其權限管理
      相關文章
      亚洲欧洲中文日韩av乱码| 亚洲av永久综合在线观看尤物| 香蕉大伊亚洲人在线观看| 亚洲福利视频网址| 亚洲成人在线网站| 久久久久亚洲AV成人无码网站| 亚洲高清成人一区二区三区| 亚洲精品麻豆av| 亚洲乱码中文字幕手机在线 | 亚洲AⅤ视频一区二区三区| 爱爱帝国亚洲一区二区三区| 偷自拍亚洲视频在线观看| 亚洲AV成人精品日韩一区18p| 亚洲а∨天堂久久精品| 亚洲精品无码av天堂| 国产亚洲大尺度无码无码专线| 国产成人A亚洲精V品无码| 国产亚洲日韩在线三区| 亚洲精品无码不卡在线播放HE| 亚洲免费观看视频| 亚洲精品蜜桃久久久久久| 亚洲第一精品在线视频| 亚洲高清资源在线观看| 亚洲一本之道高清乱码| 亚洲欧美一区二区三区日产| 日韩亚洲翔田千里在线| 亚洲AV无码一区二区三区网址| 中文字幕亚洲一区二区va在线| 亚洲乱色熟女一区二区三区丝袜| 亚洲无线码一区二区三区| 亚洲AV无码码潮喷在线观看| 亚洲天堂中文字幕| 亚洲成在人线中文字幕| 亚洲熟妇无码一区二区三区导航| 国产成人精品久久亚洲高清不卡| 国产国拍亚洲精品福利| 亚洲欧洲日产国码无码网站| 亚洲老熟女@TubeumTV| 亚洲一卡2卡3卡4卡国产网站| 亚洲精品国产字幕久久不卡| 亚洲综合精品一二三区在线|