我需要將uint8數組中的值加載到128個NEON寄存器中。有一個類似的question。但是沒有好的答案。NEON:將uint8_t數組加載到128位寄存器中
我的解決辦法是:
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位數據加載到128位的32位?
編輯:
感謝@FrankH。
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
所以沒有多餘的商店,這是很快速。但仍然是第一個解決方案比x1.5慢。
但是vzip_u8返回uint8x8x2_t,而vzipq_u8需要uint8x16_t。 – Max
試過這個:ld32x4 = vzipq_u8(vzipq_u8(vld1q_u8(arr),q_zero).val [0],q_zero).val [0];但它比我的變體慢了約30%。不管怎麼說,還是要謝謝你! – Max
不 - 不要做'.val [...''的事。這將強制存儲/重新加載。使用'vreinterpretq _ *()' - 根據類型/大小將uint8x8x2_t轉換爲uint8x16_t和uint8x16x2_t成爲uint8x32_t等等,它只是告訴編譯器以不同的方式解釋一組兩個/四個霓虹燈區域。 –