我正在编写一个iPhone应用程序,需要每1/30秒计算一个数字的平方根约2000次。 sqrt()在计算机上工作正常,但在iPhone或iPad上帧速率降至10 FPS左右,我已经优化了其余的代码。我听说通过估计平方根可以大大加快这个速度,但我找不到任何代码来执行此操作。我只需要一个或两个小数位的精度。任何关于如何做到这一点的建议,或其他加快速度的方法都将受到赞赏。
谢谢!
答案 0 :(得分:10)
除非您实际上需要平方根,否则请比较平方值而不是原始值和平方根。
如果你只需要比较,那么Squaring比采用平方根要快得多(也更准确)。这是大多数游戏的做法。
答案 1 :(得分:4)
您是否知道要查找平方根的值的范围?假设您的值范围为0到10.您可以预先计算数组:
sqrt_val[0] = 0;
sqrt_val[1] = 1;
sqrt_val[2] = // the sqrt of 2
...
sqrt_val[10] = // the sqrt of 10
然后在运行时,您获取想要sqrt的数字,将其转换为整数(例如3.123变为3)并将其用作索引(3)以查找预先计算的值。
当然,如果你想要更精细的分辨率,你可以增加数组中的项目数。
答案 2 :(得分:3)
首先,你确定平方根实际上是瓶颈吗?你介绍过吗?即使在手机上,每1/30秒的2000平方根实际上并不是那么多。 ARM文档引用了33个周期的单精度平方根和60个周期的双精度;一个600mHz的处理器可以每秒 1000万平方根(如果指令是流水线的话,则更多)。
如果您有配置文件,并且平方根确实是瓶颈,您将需要使用NEON vrsqrte.f32
指令。该指令非常快,并且同时为您提供四个浮点数的近似倒数平方根。然后,您可以使用vmul.f32
指令来获得近似平方根(尽管对于许多用途,倒数比平方根本身更有用)。
答案 3 :(得分:2)
也许这适合你:
Fast inverse square root
如果这种方法不能提供您所需的精度,那么还有很多其他迭代方法,您可以在速度和精度之间选择或多或少的精确度:
Methods of computing square roots
答案 4 :(得分:2)
您希望估算的准确度如何?如果你知道你的估计与真实的平方有多接近,那么Newton's Method就是你的朋友。
您知道传递给sqrt的值的范围吗?如果是这样,您可以组成一个在启动时预先计算的查找表(或者甚至在启动时从磁盘读取,具体取决于更快的结果)。找到表格中最接近您输入的内容,即可获得估算值。
答案 5 :(得分:2)
您可以在iPhone上进行的最简单的更改是使用sqrtf()而不是sqrt()。单精度浮点数学比双精度快得多,特别是在3GS年份和更新的设备上。
答案 6 :(得分:2)
如果你需要平方根来计算毕达哥拉斯三角形(sqrt(x * x + y * y)),并且x和y都是非负的,那么非常快速的逼近
max(x,y) + min(x,y)*0.333
最大误差为5.7%。注意min()和max()中的分支错误预测。
答案 7 :(得分:0)
快速的Google搜索可以显示各种链接。
答案 8 :(得分:0)
如果你有一个“正常”正浮点数或双正数,而不是一个int,并且想要使用表查找方法,你可以做两个单独的表查找,一个用于指数(重新偏置),以及一个用于尾数的几位(移位和掩码位域提取),然后将两个表的查找结果相乘。