更快的数学算法牺牲了准确性

时间:2009-12-10 16:07:41

标签: algorithm math

我正在开发一种能够为物理和渲染调用许多数学函数的游戏。已知Quake3中使用的"Fast inverse sqrt"比sqrt()快,并且它的背景很漂亮。

您是否知道任何其他算法比平时更快且准确度损失可接受?

6 个答案:

答案 0 :(得分:13)

任何连续函数(包括最常见的数学运算)都可以通过多项式在有界区间内很好地近似。这与常见数学函数通常满足的相对简单的标识(如加法则)和表查找一起,提供了构建快速逼近算法的标准技术的基础(以及系统数学中使用的高精度方法的基础)。库)。

然而,泰勒系列通常是一个糟糕的选择;对于大多数计算用途,Chebyshev或Minimax多项式具有更好的误差特性。拟合minimax多项式的标准技术是使用Remes的算法,该算法在很多商业数学软件中实现,或者如果你知道你正在做什么,你可以用一天的工作来完成你自己的实现。

为了记录,在现代处理器上应该避免使用“快速反平方根”,因为使用浮点倒数平方根估计指令(rsqrtss / rsqrtps要快得多SSE,NEON上的vrsqrte,AltiVec上的vrsqrtefp。即使是(非近似)硬件平方根在当前的英特尔处理器上速度也非常快。

答案 1 :(得分:9)

这些算法在文献中称为“近似算法”。有大量例子的标准书是Approximation Algorithms by Vijay V. Vazirani

sin x ~~ x的情况是稍微更一般的特例:查看函数的Taylor series(或周期函数的傅里叶级数)并仅计算前几个项。

另一种(有点残酷的)技术是随机组合你的函数的几个点,然后对它进行线性回归。这样,你也可以得到一个很好的多项式来描述你的函数:)。

答案 2 :(得分:5)

对于小x:sin(x)〜= x是经常在物理中使用的

答案 3 :(得分:3)

Niko有一些很好的建议,我会添加旧时尚查找表。

我在高性能实时系统中成功地多次使用查找表来查找循环函数(sin / cos / tan)。 sqrt()更难以这种方式,但是如果您的输入范围受到限制(比如屏幕像素)则很难超越速度,您可以精确地调整空间/准确度。你也可以使用查找一个公共范围,然后对一个罕见的情况下框架sqrt()函数的余量。

保罗

答案 4 :(得分:2)

从Doom源代码中,可以获得两个2D点之间的近似距离,而无需使用sqrt()或三角函数:

fixed_t P_AproxDistance(fixed_t dx, fixed_t dy )
{
    dx = abs(dx);
    dy = abs(dy);
    if (dx < dy)
        return dx+dy-(dx>>1);
    else
        return dx+dy-(dy>>1);
}

请注意x >> 1x / 2相同,但速度稍快 - 现代好的编译器会自动执行此操作,但当时它们并不是那么好。

答案 5 :(得分:1)

任何概率通常都是这样的。运行模拟10次会更快,但产生的结果不如运行模拟1000次。