两个 uint8 值之间是否存在饱和减法到 Neon 中的 int8
Is there a saturating subtract between two uint8 values into int8 in Neon
我必须在两个 unint8 向量之间做减法,然后饱和到 int8 向量。例如
uint8 a=8;
uint8 b=248;
subtract: a-b=-240
saturate cast: -240 -> -128
make sure the value is in [-128, 127]
我想要arm neon的C API
当然没有单一的 NEON 操作可以从一种类型到另一种类型同时进行饱和和算术运算,具有第三种中间类型的精度,但它似乎有两种可能:
无符号加宽减法 (vsubl
) 将在不损失精度的情况下将中间结果计算为 uint16。由于 NEON 使用二进制补码,我们利用了以下事实:这里的任何整数下溢都等同于带符号的减法,并且我们仍然只有最多 9 位数据,所以很高兴将其转换为带符号的 int16
。然后我们可以执行缩小饱和度 (vqmovn
) 以将其降低到带符号的 int8
以获得所需的结果。
将其放在内部函数中给了我这个,这似乎可以完成工作:
int8x8_t dothething(uint8x8_t a, uint8x8_t b) {
uint16x8_t tmp = vsubl_u8(a, b);
return vqmovn_s16(vreinterpretq_s16_u16(tmp));
}
我必须在两个 unint8 向量之间做减法,然后饱和到 int8 向量。例如
uint8 a=8;
uint8 b=248;
subtract: a-b=-240
saturate cast: -240 -> -128
make sure the value is in [-128, 127]
我想要arm neon的C API
当然没有单一的 NEON 操作可以从一种类型到另一种类型同时进行饱和和算术运算,具有第三种中间类型的精度,但它似乎有两种可能:
无符号加宽减法 (vsubl
) 将在不损失精度的情况下将中间结果计算为 uint16。由于 NEON 使用二进制补码,我们利用了以下事实:这里的任何整数下溢都等同于带符号的减法,并且我们仍然只有最多 9 位数据,所以很高兴将其转换为带符号的 int16
。然后我们可以执行缩小饱和度 (vqmovn
) 以将其降低到带符号的 int8
以获得所需的结果。
将其放在内部函数中给了我这个,这似乎可以完成工作:
int8x8_t dothething(uint8x8_t a, uint8x8_t b) {
uint16x8_t tmp = vsubl_u8(a, b);
return vqmovn_s16(vreinterpretq_s16_u16(tmp));
}