我正在寻找一种将元素从8位源数组(uint8_t*
)加载到数据格式为uint16x8_t
或更好的uint16x8x3_t
的AArch64neon/ASIMD寄存器的方法.因此,基本上,源数组中的每个字节都必须作为短字节加载到寄存器中.
在for循环中,我必须在每次迭代中使用一批新的值进行加载.
我找不到任何ASIMD内部函数来做这件事,但也许我遗漏了一些东西.我目前的方法是首先将元素加载为uint8x8x3_t
,执行扩大左移(使用vmovl_u8
,使元素变为uint16x8_t
),但这似乎非常低效:
uint8x8x3_t bgrChunk = vld3_u8(bgr);
uint16x8_t b = vmovl_u8(bgrChunk.val[0]);
uint16x8_t g = vmovl_u8(bgrChunk.val[1]);
uint16x8_t r = vmovl_u8(bgrChunk.val[2]);
bgr += 24; // Required for next iteration
我也try 了以下方法,但这个性能比上面的更差;
uint16_t bgrValues[] = { bgr++, bgr++, bgr++, ... repeat up to 24 elements ..., bgr++, bgr++ };
uint16x8x3_t bgrChunk = vld3q_u16(bgrValues);
有没有更有效的方法来做到这一点,或者我是不是错过了一些内在的东西,可以让我更容易做到这一点?
Edit; Extended example of what I want
假设我有一个数组uint8_t*
,其值为{ 5,33,102,153. }
有没有一种方法可以将每个8位individual元素作为16位值直接加载到寄存器中,以便该寄存器将包含16-bit个值{5,33,102,153...}?
void foo(uint8_t* bgr, uint16_t width, uint16_t height) {
for (uint16_t y = 0; y < height; y++) {
for (uint16_t x = 0; x < width; x += 8) {
// I want to load 8-bit values as 16-bit values here. Is there a more efficient way to do this than the code below?
uint8x8x3_t bgrChunk = vld3_u8(bgr);
uint16x8_t b = vmovl_u8(bgrChunk.val[0]);
uint16x8_t g = vmovl_u8(bgrChunk.val[1]);
uint16x8_t r = vmovl_u8(bgrChunk.val[2]);
bgr += 24;
// ... Some operations working on the loaded data
}
}
}