我正在为使用大量浮点运算和三角函数的 ARM-Target 编写代码。AFAIK 浮点计算比 int 慢得多(尤其是在 ARM 上)。准确性并不重要。
我考虑过使用比例因子(0*pi 到 2*pi 的 pe 范围变为 int 0 到 1024)和查找表来实现我自己的三角函数。这是一个好方法吗?有没有其他选择?
目标平台是运行 ubuntu 的 Odroid U2 (Exynos4412) 和许多其他东西(网络服务器等)。
(允许 c++11 和 boost/库)
我正在为使用大量浮点运算和三角函数的 ARM-Target 编写代码。AFAIK 浮点计算比 int 慢得多(尤其是在 ARM 上)。准确性并不重要。
我考虑过使用比例因子(0*pi 到 2*pi 的 pe 范围变为 int 0 到 1024)和查找表来实现我自己的三角函数。这是一个好方法吗?有没有其他选择?
目标平台是运行 ubuntu 的 Odroid U2 (Exynos4412) 和许多其他东西(网络服务器等)。
(允许 c++11 和 boost/库)
如果您的目标平台有数学库,请使用它。如果它有什么好处,它是由考虑速度的专家编写的。您不应该基于对快或慢的猜测来设计代码。如果您没有实际测量值或处理器规格,并且您不知道应用程序中的三角函数会消耗大量时间,那么您没有充分的理由更换数学库。
浮点指令通常比整数指令具有更长的延迟,但它们是流水线的,因此吞吐量可能相当。(例如,一个浮点单元可能有四个阶段来完成这项工作,因此一条指令需要四个周期来完成所有阶段,但您可以在每个周期中将一条新指令推入第一阶段。)流水线是否是否足以提供与整数实现相当的性能很大程度上取决于目标处理器、所使用的算法以及实现者的技能。
如果在您的情况下使用数学例程的自定义实现是有益的,那么它们应该如何设计在很大程度上取决于具体情况。正确的建议取决于要支持的域(只是 0 到 2π?–2π 到 +2π?可能更大的值,必须折叠到 -π 到 π?),需要支持哪些特殊情况(传播 NaN?),所需的准确性,处理器中还发生了什么(是否正在使用大量内存,或者我们可以依赖缓存中剩余的查找表?)等等。
三角函数的一个重要部分是处理各种情况(NaN、无穷大、小值)并减少模 2π 的参数。可以实现不处理特殊情况或执行参数缩减但仍使用浮点的精简例程。
One possible alternative is trigint:
Exynos 4412 使用 Cortex-A9 内核[1],它具有完全流水线的单精度和双精度浮点。没有理由像一些较旧的 ARM 内核那样诉诸整数运算。
根据您的特定精度要求(特别是如果您可以保证输入在有限范围内),您可以使用比标准库中可用的实现快得多的近似值。需要更多关于您的确切使用情况的信息才能提供合理的建议。
您应该使用“定点”数学而不是浮点数。
大多数 ARM 处理器(7 及以上)在定点上允许 32 位分辨率。所以你可以很容易地达到 1E-3 弧度。但真正的问题是您需要多少准确度的结果?
是否使用查找表、带插值的查找表或函数取决于您的系统上有多少数据空间。查找表执行速度最快,但使用的数据空间最多。函数使用最少的数据量,但需要最多的执行时间。插值可能是一种缓解措施,它允许更小的表和一些额外的处理。