2014-02-18 30 views
0

我對複數進行了大量計算(通常是一個數組,其中包含一個由兩個浮點數組成的結構來表示im和re;請參見下文),並希望用NEON C intrinsics加速它們。這將是真棒,如果你可以給我如何加快事情是這樣一個例子:具有複數的霓虹內在函數

for(n = 0;n < 1024;n++,p++,ptemp++){ // get cir_abs, also find the biggest point (value and location). 
    abs_squared = (Uns32)(((Int32)(p->re)) * ((Int32)(p->re)) 
        + ((Int32)(p->im)) * ((Int32)(p->im))); 
    // ... 
} 

p是這種類型的數組:

typedef struct { 
    Int16 re; 
    Int16 im; 
} Complex; 

我已經通過的第12章讀「 ARM C語言擴展「,但在理解如何在這裏加載和存儲我的類型結構以對其進行計算時仍然存在問題。

+1

我認爲它更適合將它張貼在另一個StackExchange的網站,如'代碼Review'例如。 –

+0

這樣做:https://codereview.stackexchange.com/questions/42051/neon-intrinsics-with-complex-numbers – marcel

回答

4

使用vld2*內部函數在加載時將reim拆分爲不同的寄存器,然後分別對它們進行處理,例如,

Complex array[16]; 

const int16x8x2_t vec_complex = vld2q_s16((const int16_t*)array); 
const int16x8_t vec_re = vec_complex.val[0]; 
const int16x8_t vec_im = vec_complex.val[1]; 
const int16x8_t vec_abssq = vmlaq_s16(vmulq_s16(vec_re, vec_re), vec_im, vec_im); 

上面的代碼鐺3.3生成

vld2.16 {d18, d19, d20, d21}, [r0] 
vmul.i16 q8, q10, q10 
vmla.i16 q8, q9, q9 
+0

謝謝,似乎是我正在尋找的東西。但是,我會產生溢出,不是嗎?所以我可能會用int32x4類型做所有事情。 – marcel

+0

您可以類似地訪問'int16x8_t'的int16x4_t部分並使用'vaddl_s16' /'vmull_s16' /'vmlal_s16'來產生4個32位結果'int32x4_t'(注意,該操作輸入64位SIMD寄存器並輸出128位SIMD寄存器)。 –

+0

例如'const int32x4_t vec_abssq_lo = vmlal_s16(vmull_s16(vget_low_s16(vec_re),vget_low_s16(vec_re)),vget_low_s16(vec_im),vget_low_s16(vec_im));' –