簡體   English   中英

數據類型與NEON內在函數的兼容性

[英]Data type compatibility with NEON intrinsics

我正在使用來自C ++代碼的NEON內在函數進行ARM優化。 我理解並掌握了大多數打字問題,但我仍然堅持這一點:

指令vzip_u8返回uint8x8x2_t值(實際上是兩個uint8x8_t的數組)。 我想將返回的值分配給普通的uint16x8_t 我認為沒有適當的vreinterpretq內在實現它,並且簡單的強制轉換被拒絕。

一些定義要清楚地回答......

NEON有32個寄存器,64位寬(雙視圖為16個寄存器,128位寬)。

NEON單元可以查看相同的寄存器組:

  • 16個128位四字寄存器,Q0-Q15
  • 32個64位雙字寄存器,D0-D31。

uint16x8_t是一種需要128位存儲的類型,因此它需要位於quadword寄存器中。

ARM NEON Intrinsics在ARM®C語言擴展中有一個稱為vector array data type的定義:

...用於加載和存儲操作,表查找操作,以及返回一對向量的結果操作類型。

vzip指令

...交錯兩個向量的元素。

vzip Dd,Dm

並且具有內在的相似性

uint8x8x2_t vzip_u8 (uint8x8_t, uint8x8_t) 

從這些我們可以得出結論,uint8x8x2_t實際上是兩個隨機編號雙字寄存器的列表,因為vzip指令對輸入寄存器的順序沒有任何要求。

現在答案是......

uint8x8x2_t可以包含非連續的兩個雙字寄存器,而uint16x8_t是由兩個連續雙字寄存器組成的數據結構,第一個具有偶數索引(D0-D31-> Q0-Q15)。

因此,您無法將具有兩個雙字寄存器的vector array data type轉換為四字寄存器....

編譯器可能足夠聰明,可以幫助您,或者您可以強制轉換,但是我會檢查生成的程序集的正確性和性能。

您可以使用vcombine_ * intrinsics從兩個64位向量構造一個128位向量。 因此,你可以達到你想要的效果。

#include <arm_neon.h>

uint8x16_t f(uint8x8_t a, uint8x8_t b)
{
    uint8x8x2_t tmp = vzip_u8(a,b);
    uint8x16_t result;
    result = vcombine_u8(tmp.val[0], tmp.val[1]);
    return result;
}

我找到了一個解決方法:假設uint8x8x2_t類型的val成員是一個數組,因此它被視為一個指針。 轉換和引用指針有效! [獲取數據地址會引發“臨時”地址警告。]

uint16x8_t Value= *(uint16x8_t*)vzip_u8(arg0, arg1).val;

事實證明,這應該編譯和執行(至少在我嘗試過的情況下)。 我沒有查看匯編代碼,因此我無法授予它正確實現(我的意思是只將值保存在寄存器中,而不是寫入/讀取內存。)

遇到了同樣的問題,所以我介紹了一種靈活的數據類型

因此,我現在可以定義以下內容:

typedef NeonVectorType<uint8x16_t> uint_128bit_t; //suitable for uint8x16_t, uint8x8x2_t, uint32x4_t, etc.
typedef NeonVectorType<uint8x8_t> uint_64bit_t; //suitable for uint8x8_t, uint32x2_t, etc.

它是4.5和4.6系列中GCC(現已修復)的一個錯誤。

Bugzilla鏈接http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48252

請從此錯誤中獲取修復並應用於gcc源並重建它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM