0

我有一个 12 位数据的缓冲区(存储在 16 位数据中),需要转换为 8 位(移位 4)

NEON 如何加速这种处理?

谢谢您的帮助

卜拉欣

4

2 回答 2

3

冒昧地假设了下面解释的一些事情,但是与天真的非 NEON 版本相比,这种代码(未经测试,可能需要一些修改)应该提供良好的加速:

#include <arm_neon.h>
#include <stdint.h>

void convert(const restrict *uint16_t input, // the buffer to convert
             restrict *uint8_t output,       // the buffer in which to store result
             int sz) {                       // their (common) size

  /* Assuming the buffer size is a multiple of 8 */
  for (int i = 0; i < sz; i += 8) {
    // Load a vector of 8 16-bit values:
    uint16x8_t v = vld1q_u16(buf+i);
    // Shift it by 4 to the right, narrowing it to 8 bit values.
    uint8x8_t shifted = vshrn_n_u16(v, 4);
    // Store it in output buffer
    vst1_u8(output+i, shifted);
  }

}

我在这里假设的事情:

  • 您正在使用无符号值。如果不是这种情况,无论如何都会很容易适应(uint*-> int**_u8->*_s8*_u16-> *_s16
  • 由于这些值是 8 乘 8 加载的,因此我假设缓冲区长度是 8 的倍数,以避免出现极端情况。如果不是这种情况,您可能应该人为地将其填充为 8 的倍数。

最后,NEON 文档中使用的 2 个资源页面:

希望这可以帮助!

于 2013-09-10T15:29:58.607 回答
1
prototype : void dataConvert(void * pDst, void * pSrc, unsigned int count);
    1:
    vld1.16 {q8-q9}, [r1]!
    vld1.16 {q10-q11}, [r1]!
    vqrshrn.u16 d16, q8, #4
    vqrshrn.u16 d17, q9, #4
    vqrshrn.u16 d18, q10, #4
    vqrshrn.u16 d19, q11, #4
    vst1.16 {q8-q9}, [r0]!
    subs r2, #32
    bgt 1b

q 标志:饱和度

r 标志:四舍五入

如果是签名数据,请将 u16 更改为 s16。

于 2013-09-11T16:02:17.210 回答