【发布时间】:2021-12-13 17:29:00
【问题描述】:
我正在尝试使用 ARM Neon 内在函数来实现圆函数。
这个函数看起来像这样:
float roundf(float x) {
return signbit(x) ? ceil(x - 0.5) : floor(x + 0.5);
}
有没有办法使用 Neon 内在函数来做到这一点?如果没有,如何使用 Neon 内部函数来实现这个功能?
编辑
计算两个浮点数的乘积后,调用roundf(在armv7和armv8上)。
我的编译器是clang。
这可以通过 vrndaq_f32: https://developer.arm.com/architectures/instruction-sets/intrinsics/#f:@navigationhierarchiessimdisa=[Neon]&q=vrndaq_f32 for armv8 来完成。
如何在 armv7 上执行此操作?
编辑
我的实现
// input: float32x4_t arg
float32x4_t vector_zero = vdupq_n_f32(0.f);
float32x4_t neg_half = vdupq_n_f32(-0.5f);
float32x4_t pos_half = vdupq_n_f32(0.5f);
uint32x4_t mask = vcgeq_f32(arg, vector_zero);
uint32x4_t mask_neg = vandq_u32(mask, neg_half);
uint32x4_t mask_pos = vandq_u32(mask, pos_half);
arg = vaddq_f32(arg, (float32x4_t)mask_pos);
arg = vaddq_f32(arg, (float32x4_t)mask_neg);
int32x4_t arg_int32 = vcvtq_s32_f32(arg);
arg = vcvtq_f32_s32(arg_int32);
有没有更好的方法来实现这个?
【问题讨论】:
-
许多霓虹灯指令都包含可选的舍入。根据您要使用它的位置,最好将舍入与之前的任何操作结合起来。
-
你在做编译器吗?
-
对于霓虹灯上的
float数据没有直接舍入指令。但是,您可以使用一个小数位转换为int,然后将其用于舍入。 -
这是 32 位还是 64 位? AArch64 有
FRINTZ指令,我认为这是你想要的。 -
这是什么,四舍五入到最接近 0.0?所以它是 C
roundf()函数?正如 Nate 所说,这可以通过 AArch64 的frint来完成。 Clang 确实将round()内联为frinta: godbolt.org/z/o8arE1795。但不适用于 ARM32。
标签: c arm rounding intrinsics neon