使用 NEON/ARM 加载 8 位值

Posted

技术标签:

【中文标题】使用 NEON/ARM 加载 8 位值【英文标题】:Loading 8-bit values using NEON/ARM 【发布时间】:2012-01-27 17:10:16 【问题描述】:

我正在尝试将 char 值数组加载到 NEON 寄存器中,然后将它们视为 16 位或 32 位整数值。所以像这样......

void SubVector(short* c, const unsigned char* a, const unsigned char* b, int n)

    for(int i = 0; i < n; i++)
    
        c[i] = (short)a[i] - (short)b[i];
    

我不确定如何加载数据。我应该将 8 位数据加载到通道中,然后将寄存器重新解释为短路吗?还是加载和转换?最快的方法是什么?

有没有人举例说明他们将如何使用 NEON 内在函数做到这一点?

谢谢!

【问题讨论】:

【参考方案1】:

NEON 具有加法和减法指令,可以将值从 8->16、16->32 或 32->64 位扩展。你可以像这样一次做 8 个:

uint8x8_t u88_a, u88_b;
uint16x8_t u168_diff;

u88_a = vld1_u8(a); // load 8 unsigned chars from a[]
u88_b = vld1_u8(b); // load 8 unsigned chars from b[]
u168_diff = vsubl_u8(u88_a, u88_b); // calculate the difference and widen to 16-bits

【讨论】:

我正在尝试做同样的事情。然而,当计算两个 uint8 之间的差异时,结果应该是 int16 而不是 uint16……那么这个内在函数有什么用呢?我需要重新解释等以获得负面结果。 减法对于有符号或无符号值是相同的,所以你只需要重新解释输出(基本上在 asm 代码中生成一个 NOP)。

以上是关于使用 NEON/ARM 加载 8 位值的主要内容,如果未能解决你的问题,请参考以下文章

如何知道在LDRH指令中哪些半字位(8位)要移位到Rd(目标寄存器)?

从两个 8 位值中找到 14 位值的函数的反面是啥?

在 Python 3.x 中转换 8 位和 7 位值

将 16 位值的 __m256i 打包(饱和)到 8 位值的 __m128i?

Z80汇编:如何将带符号的8位值添加到16位寄存器?

如何在 GCC 下强制设置“布尔”的大小