我正在嘗試使用 ARM Neon 內在函式實作輪函式。
這個函式看起來像這樣:
float roundf(float x) {
return signbit(x) ? ceil(x - 0.5) : floor(x 0.5);
}
有沒有辦法使用 Neon 內在函式來做到這一點?如果沒有,如何使用 Neon 內在函式來實作此功能?
已編輯
計算兩個浮點數的乘積后,呼叫roundf(在armv7和armv8上)。
我的編譯器是叮當的。
這可以通過以下方式完成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);
有沒有更好的方法來實作這一點?
uj5u.com熱心網友回復:
您定義是很重要的,其圓你真正想要的形式。請參閱維基百科以了解有多少舍入選項。
從您的代碼片段中,您要求商業或對稱舍入,從零開始舍入。對于 ARMv8 / ARM64,vrndaq_f32應該這樣做。
SSE4
_mm_round_ps和 ARMv8 ARM-NEONvrndnq_f32進行銀行家舍入,即舍入到最近(偶數)。
uj5u.com熱心網友回復:
您的解決方案在周期計數和暫存器利用率方面都非常昂貴。
提供-(2^30) <= arg < (2^30),您可以執行以下操作:
int32x4_t argi = vcvtq_n_s32_f32(arg, 1);
argi = vsraq_n_s32(argi, argi, 31);
argi = vrshrq_n_s32(argi, 1);
arg = vcvtq_f32_s32(argi);
它不需要除arg自身之外的任何其他暫存器,并且只需 4 條廉價指令即可完成。它適用于aarch32和aarch64
神印鏈接
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/341546.html
