Arm 在霓虹灯中,两个uint8值到int8之间是否存在饱和相减

Arm 在霓虹灯中,两个uint8值到int8之间是否存在饱和相减,arm,neon,Arm,Neon,我必须在两个未调整的向量之间做减法运算,然后饱和为int向量。比如说 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)将在不损失

我必须在两个未调整的向量之间做减法运算,然后饱和为int向量。比如说

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使用2的补码,我们利用了一个事实,即这里的任何整数下溢都相当于有符号减法,并且我们仍然最多只有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));
}

当然,从一种类型到另一种类型,没有单一的霓虹灯操作可以同时进行饱和和运算,精度相当于第三种中间类型,但似乎有两种操作可以实现:

无符号加宽减法(
vsubl
)将在不损失精度的情况下计算中间结果作为uint16。由于NEON使用2的补码,我们利用了一个事实,即这里的任何整数下溢都相当于有符号减法,并且我们仍然最多只有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));
}

我希望您的项目是基于一个无序的架构,如CA9或CA15。否则,滥发下面的函数将严重受到指令延迟的影响。我希望您的任务是基于一个无序的体系结构,如CA9或CA15。否则,滥发下面的函数将严重受到指令延迟的影响。我只是希望OP知道他在处理什么。现在人们想被填鸭式的喂养,而不是学习。我只是希望OP知道他在处理什么。如今,人们希望被填鸭式喂养,而不是学习。