优化毕达哥拉斯SQRT()

时间:2013-08-09 13:23:45

标签: c++ math sqrt

经过一些延迟测量测试,我发现我需要优化在具有相当慢的FPU的嵌入式CPU上完成的毕达哥拉斯三角形计算。

问题是如果这些计算发生,它们会有数字,这会弄乱时间。我无法减少绝对计算次数。但不知何故,他们需要更快......至少要因素5: - /

我目前正在考虑预处理这些计算,因为不同值的输入范围在某种程度上限制在大约300-500个排列,并且两个表项之间的插值应该足够。但我也想知道如果使用某些条件来解决这个问题,也可以加速这段代码:

float h = 0.f, v=0.f;
/// ...
float const d = std::sqrt( (h*h) + (v*v) );

这个我还没用过:

  1. 结果 d 的准确性非常有限,不超过3个小数位
  2. 三角形的腿(h,v)总是长宽比为4:3或16:9
  3. 我不知道某个整数定点计算是否可用于平方根,或者该函数是否可以替换为精度较低或以某种方式使用纵横比的函数。

    有什么想法吗?

    谢谢!

3 个答案:

答案 0 :(得分:5)

如果你知道这个比例是16:9,你可以做一点代数:

h = 16*x
v = 9*x
x = h/16
sqrt((h*h) + (v*v)) = sqrt((16*16*x*x) + (9*9*x*x))
                    = sqrt((16*16+9*9)*x*x)
                    = sqrt(16*16+9*9)*x
                    = sqrt(16*16+9*9)*h/16
                    = sqrt(16*16+9*9)/16 * h

预先计算sqrt(16*16+9*9)/16

static float const multiplier = std::sqrt(16*16+9*9)/16.0;

并使用

float const d = multiplier*h;

答案 1 :(得分:1)

我不知道你在这个嵌入式系统中有多少RAM / ROM,但是如果你有一些,预计算方块和平方根可能是要走的路。这假设您的嵌入式CPU具有缓存和/或RAM / ROM访问速度比浮点计算更快的能力。

也就是说,有计算平方根的数值方法,但我不确定它们实际上会比sqrt调用更快,无论多慢。

答案 2 :(得分:1)

你知道Boost :: math库吗? 在这里你可以找到一些有趣的根源:http://www.boost.org/doc/libs/1_54_0/libs/math/doc/html/math_toolkit/internals1/roots.html