2010-04-11 74 views
10

這與ARM霓虹燈SIMD編碼特別相關。我在視頻解碼器中爲某些模塊使用ARM Neon內置函數。我有一個矢量化的數據如下:如何使用ARM Neon intrinsics重新排序矢量數據?

在氖燈寄存器中有四個32位元素 - 比方說Q0,它的大小爲128位。

3B 3A 1B 1A 

在其他氖燈寄存器中還有另外四個32位元素,說Q1大小爲128位。

3D 3C 1D 1C 

我想最終的數據是爲了如下圖所示:

1D 1C 1B 1A 
3D 3C 3B 3A 

什麼霓虹燈instrinsics能達到預期的數據順序?

+0

錯字在最終的數據順序?應該是'3D 3C 3B 3A'? – 2010-04-11 07:20:39

+0

@ Paul R:謝謝,糾正它。 – goldenmean 2010-04-11 07:41:49

回答

9

怎麼是這樣的:

int32x4_t q0, q1; 

    /* split into 64 bit vectors */ 
    int32x2_t q0_hi = vget_high_s32 (q0); 
    int32x2_t q1_hi = vget_high_s32 (q1); 
    int32x2_t q0_lo = vget_low_s32 (q0); 
    int32x2_t q1_lo = vget_low_s32 (q1); 

    /* recombine into 128 bit vectors */ 
    q0 = vcombine_s32 (q0_lo, q1_lo); 
    q1 = vcombine_s32 (q0_hi, q1_hi); 

理論上這應該編譯,只留下兩個移動指令,因爲vget_high和vget_low只是重新詮釋128位Q寄存器,兩個64位d個寄存器。 vcombine otoh只是編譯爲一個或兩個動作(取決於寄存器分配)。

哦 - 並且輸出中整數的順序可能完全是錯誤的。如果是這樣,只需將參數交換到vcombine_s32。

3

看起來你應該能夠使用VTRN指令(例如vtrnq_u32)。

+0

@Paul:vtrnq_u32不起作用。其實我需要做一些類似VTRN.64的東西,但可悲的是,沒有像VTRN.64那樣的指令/內在。 – goldenmean 2010-04-11 07:40:10

+0

@goldenmean:對不起 - 我明白你的意思了 - NEON似乎缺少一般用途的排列/洗牌操作。 – 2010-04-11 07:46:02

+0

鏈接關閉了... – Antonio 2015-03-20 13:58:58

4

記住每個q寄存器由兩個d寄存器組成,例如q0的低位部分是d0和高位部分d1。所以實際上,這個操作只是交換d0和d3(或者d1和d2,從數據表示中不完全清楚)。甚至有一個交換指令可以在一條指令中完成!我不知道Neon intrinsics(我直接在彙編中編寫代碼),但是如果使用intrinsics不能完成這些工作,我會感到驚訝。

2

皮埃爾是對的。

vswp d0,d3

這樣做。

@Pierre: 幾個月前,我在博客上閱讀關於NEON的文章。我驚喜地發現有一個像我這樣的人 - 編寫手工優化的彙編代碼,包括ARM和NEON。 很高興見到你。