如何解决如何使用Arm v7霓虹灯内在函数获取Q寄存器int64x2_t的绝对值?
例如:
int64x2_t a{1,-1};
auto abs_val = vabsq_s64(a);//But this intrinsic is only or A64 architecture.
谢谢!
解决方法
如果您要执行很多64位操作,则应该对硬件进行三思。在ARMv7上,有很多功能缺少64位版本,因此,如果可以升级到AArch64,则确实应该。假设您没有该选择...
基本上,vabsq_s64
的每个泳道都是这样的:
res[i] = a[i] < 0 ? -a[i] : a[i];
您只需要使用其他内在函数即可。
让我们先处理一下否定。 NEON有一个vnegq_s64
函数可以解决这个问题,但是它仅适用于AArch64。但是,我们可以只从0中减去a:vsubq_s64(vdupq_n_s64(0),a)
。
现在,我们必须在取反值和原始值(这是vbslq_s64
的域)之间进行选择。 vbslq_s64
的第一个参数是一个掩码,用于确定要获取每个位的值的其他哪个参数。基本上,vbslq_s64(a,b,c)
在逻辑上类似于(a & b) | (~a & c)
。
要使用vbslq_s64
,我们首先需要一个掩码,当我们要使用一个值时,该通道中的全零,而当我们要使用另一个值时,则全为零。如果您使用的是AArch64,我会说要使用vcltzq_s64
,但不是。甚至vcltq_s64()
都仅适用于AArch64,但这没关系,因为总有更好的方法……只使用右移算术移位,它将以符号位移位(负数为1,正数为0)。您希望将符号位广播到每个通道的每个位,因此对于一个64位的值应为vshrq_n_s64(a,63)
。
当然,vbslq_s64
的第一个参数为uint64x2_t
,但是您拥有的是int64x2_t
,因此您需要使用vreinterpretq_u64_s64
进行转换。
将它们放在一起:
int64x2_t my_vabsq_s64(int64x2_t a) {
return vbslq_s64(
vreinterpretq_u64_s64(vshrq_n_s64(a,63)),vsubq_s64(vdupq_n_s64(0),a),a);
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。