1. 程式人生 > >NEON的Registers, vectors, lanes and elements

NEON的Registers, vectors, lanes and elements

NEON的Registers, vectors, lanes and elements

NEON指令和浮點指令使用相同的暫存器檔案,稱之為“NEON和浮點暫存器檔案”。

它跟ARM core 暫存器檔案完全區分開。NEON和浮點暫存器檔案是一組可以作為32-bit、64-bit或128-bit的暫存器來訪問。對於一個指令,哪個暫存器是可用的依賴於它是一個NEON指令還是一個VFP指令。本文把NEON和浮點暫存器作為NEON暫存器。一些VFP和NEON指令在通用暫存器和NEON暫存器之間移動資料,或使用ARM通用暫存器來定址記憶體。

NEON暫存器的記憶體是相同資料型別的元素向量。一個向量被分割成通道(lanes),每個通道包含一個數值,稱之為“元素”。

通常,每個NEON指令會並行執行n個操作,這裡的n是輸入向量分割成的通道的個數。每個操作包含在通道內。不會考慮到一個通道到另一個通道間的進位或溢位。

一個NEON向量的通道的個數依賴於向量的大小和向量中的數值元素:

  1. 64-bitNEON向量可以包含:
  1. 8x8-bit
  2. 4x16-bit
  3. 2x32-bit
  4. 1x64-bit
  1. 128-bitNEON向量可以包含:
  1. 16x8-bit
  2. 8x16-bit
  3. 4x32-bit
  4. 2x64-bit

元素排序

圖1-1 顯示了向量中的元素的排序,從最低位開始。這意味著,元素0使用了暫存器的最低有效位。

圖 1-1  元素與通道

圖 1-2顯示了 VADD.I16 Q0, Q1, Q2 指令是如何並行執行Q1和Q2內的8x16-bit整數add操作,把結果儲存到Q0中。

圖 1-2  8 way 16-bit integer add operation

​​​​​​​Register overlap

圖 1-3 顯示NEON和浮點暫存器檔案,暫存器怎樣重疊的。

NEON單元把暫存器檔案看作:

  1. 16個 128-bit Q,或 4字,暫存器,Q0-Q15。
  2. 32個64-bit D,或雙字,暫存器,D0-D31。(16個 64-bit D 暫存器VFPv3-D16)。

D暫存器的對映為:

  1. D<2n>對映為Q<n>的低半部分;
  2. D<2n+1>對映為Q<n>的高半部分;
  1. Q和D寄存的結合
  2. NEON單元暫存器不能直接訪問一個32-bit VFP S暫存器。見NEON和浮點暫存器檔案的VFP 角度。
  1.  S<2n>對映到 D<n>的低半部分;
  2. S<2n+1>對映到D<n>的高半部分。

圖 1-3   NEON and floating-point register file

所有這些暫存器在任何時候都能訪問。軟體並不需要精確地在它們之間切換,因為使用的指令會決定合適的view。

在圖 1-4 中,S\D和Q暫存器是相同暫存器Q0的不同view。:

  1. NEON單元可以把Q0作為一個128-bit暫存器訪問。
  2. NEON單元可以把Q0作為2個連續的64-bit暫存器D0和D1來訪問。
  3. NEON單元不能單獨把Q0作為32-bit S 暫存器訪問。如果存在VFP單元,可以把它當作S0、S1、S2和S3來訪問。

圖 1-4   Register overlap

​​​​​​​Scalar data

標量資料是指一個單一數值,而不是一個包含多個值的向量。一些NEON指令使用一個標量操作符。一個暫存器內的標量可以通過到向量的index來訪問。用於訪問向量的單個元素的陣列標識是 Dm[x]或 Qm[x],其中, x是向量 Dm或 Qm的索引。

指令  VMOV.8 D0[3], R3  移動暫存器R3中的最低有效位元組到暫存器D0的第四個位元組中。

圖 1-5  Moving a scalar to a lane

NEON標量可以是8-bit、16-bit、32-bit或64-bit值。與乘法指令不同,訪問標量的指令可以訪問暫存器檔案中的任何元素。

乘法指令只能允許16-bit或32-bit標量,並且只能訪問暫存器檔案中的前32個標量:

  1. 16-bit標量限制在暫存器 D0[x]-D7[x],x的範圍是0到3。
  2. 32-bit標量限制在暫存器 D0[x]-D15[x],x的範圍是0到1.