4

我想使用霓虹灯指令 SIMD 和臂组件计算 4 个点的大小和角度。大多数语言都有一个内置库,在我的例子中是 C++,它计算角度(atan2),但只计算一对浮点变量(x 和 y)。我想利用处理 q 寄存器的 SIMD 指令来计算 atan2 的 4 个值的向量。

精度要求不高,速度更重要。


我已经有一些汇编指令可以计算 4 个浮点寄存器的大小,并且对于我的应用程序来说具有可接受的精度。q1 包含 4 个“x”值(x1、x2、x3、x4)。q2 包含 4 个“y”值(y1、y2、y3、y4)。q7 包含 4 个结果的大小 (x1^2 + y1^2, x2^2 + y2^2, x3^2 + y3^2, x4^2 + y4^2)。

vmul.f32 q7, q1, q1  
vmla.f32 q7, q2, q2    
vrecpe.f32  q7, q7   
vrsqrte.f32 q7, q7 

使用 SIMD 指令计算两个向量的近似 atan2 的最快方法是什么?

4

1 回答 1

6

有关现有的单值浮点实现,请参见math-neon 。由于它没有(或很少)条件,它应该很好地转换为SIMD实现。

由于 ARM NEON 没有直接计算此值的指令,因此有多种技术可以创建比泰勒级数更好的近似值。具体来说,最小-最大方法为近似提供了一个很好的多项式候选。 min-max是指最小化最大误差;切比雪夫近似通常非常好。

DSP 大师函数逼近的不同方法有详细说明。网上也有很多书籍。您可以使用matlaboctave或其他一些工具包搜索最佳多项式。通常,您需要将其与rangeprecision绑定。一旦你对单个值有了一个好的算法,将它扩展到任何类型的SIMD应该是微不足道的。

问题计算 atan2参考了Apple 的 atan.c源。代码中的系数很可能来自我上面给出的内容。此代码的问题在于它不能很好地扩展到SIMD,因为atan()近似是分段的,并且您需要根据范围不同的系数。对于您的SIMD,您需要在整个范围内使用相同的系数(乘数、除数、方程)。

Abramowitz 和 Stegun:数学函数手册有一章是关于循环函数的,第 4.4.28 节给出了一个对数公式。这似乎类似于eglibc的实现。

于 2013-08-12T14:16:44.897 回答