我正在学习 ARM-v8 Aarch64 SIMD 指令,希望可以优化一些计算。在本例中,我正在寻找 4xf32 向量上的模运算。
如何使用 NEON 指令集实现求模?
注意:我实际上正在寻找一些东西来确保我的角度值保持在 -PI 和 +PI 之间(循环,而不是钳位),所以我也对其他解决方案感兴趣。
注意:目前我正在尝试使用 C 中的 arm_neon.h 标头来完成此操作,但我可能在某些时候直接使用汇编来完成此操作,以进一步优化组合指令,而不将结果存储在变量中。
Armv8-A ASIMD 指令集扩展没有模指令,既没有针对浮点的指令,也没有针对整数的指令。但是,对于除数 1,您可以通过使用“转换为整数”对数字进行四舍五入来模拟模数,然后从四舍五入的数字中减去。因此,您可以通过这些恒等式来实现模运算:
fmod(a, 1) = a - round_towards_zero(a)
fmod(a, b) = fmod(a/b, 1) * b
请注意,在您的情况下,
b
是一个常数,所以这变成:
fmod(a, b) = a - round_towards_zero(a * 1/b) * b
这就变成了三个指令:
a
和1/b
的乘法、“向零舍入”和“乘法和减法”运算。为了获得更好的性能,您应该考虑保持角度预先缩放,以便它们位于 (−1, +1) 的开区间内。