assembly - 使用 ARM NEON 汇编对 atan2 进行 SIMD 向量化

标签 assembly arm vectorization neon atan2

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

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

<小时/>

我已经有一些汇编指令可以计算 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 的最快方法是什么?

最佳答案

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

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

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

问题calculate atan2引用 Apple's atan.c来源。代码中的系数很可能源 self 上面给出的内容。此代码的问题是它无法扩展到 SIMD,并且 atan() 近似是分段的,并且根据范围需要不同的系数。对于您的 SIMD,您将需要在整个范围内使用相同的系数(乘数、除数、方程)。

Abramowitz and Stegun: Handbook of Mathematical Functions有一个关于循环函数的章节,第 4.4.28 节给出了对数公式。这似乎类似于 eglibc实现。

关于assembly - 使用 ARM NEON 汇编对 atan2 进行 SIMD 向量化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18187492/

相关文章:

windows - 将数组传递给 x86 asm 中的函数

python - 二维数组差异的 Numpy 矢量化

python - 以矢量化方式连接给定开始、结束数字的范围数组 - NumPy

c - 仅左移数字的一部分

c++ - 命名空间和私有(private)变量如何在汇编中工作?

assembly - NASM 错误 : invalid operands in non-64-bit mode

c - 在适用于 ARM Cortex M4f 的 Code Composer studio 中将堆栈指针的值保存在 C 变量中

assembly - 如何在没有计时器的情况下将 ARM Cortex M0+ 延迟 n 个周期?

ios - 如何在 iOS 上实现协程

r - 使用循环(或向量化)通过向量中的多个元素对列表进行子集化