2

uint8 配列から 128 NEON レジスタに値をロードする必要があります。同様の質問があります。しかし、良い答えはありませんでした。

私の解決策は次のとおりです。

uint8_t arr[4] = {1,2,3,4};

//load 4 of 8-bit vals into 64 bit reg
uint8x8_t _vld1_u8 = vld1_u8(arr);

//convert to 16-bit and move to 128-bit reg
uint16x8_t _vmovl_u8 = vmovl_u8(_vld1_u8);

//get low 64 bit and move them to 64-bit reg
uint16x4_t _vget_low_u16 = vget_low_u16(_vmovl_u8);

//convert to 32-bit and move to 128-bit reg
uint32x4_t ld32x4 = vmovl_u16(_vget_low_u16);

これはうまくいきますが、このアプローチは最速ではないようです。8ビットデータを32ビットとして128 regにロードするためのより良い、より高速な方法があるでしょうか?

編集:

@FrankHに感謝します。ハックを使用して2番目のバージョンを思いつきました:

uint8x16x2_t z = vzipq_u8(vld1q_u8(arr), q_zero);
uint8x16_t rr = *(uint8x16_t*)&z;
z = vzipq_u8(rr, q_zero);
ld32x4 = *(uint8x16_t*)&z;

要約すると、次のアセンブリになります (コンパイラの最適化がオンの場合)。

vld1.8 {d16, d17}, [r5]
vzip.8 q8, q9
vorr   q9, q4, q4
vzip.8 q8, q9

したがって、冗長なストアはなく、かなり高速です。それでも、最初のソリューションよりも約 1.5 倍遅くなります。

4

1 に答える 1