OpenTK的Vector2.Length是Vector2.LengthFast的两倍

时间:2012-11-16 21:18:26

标签: .net xamarin.ios opentk sqrt

OpenTK库以及它们MonoTouch和MonoDroid包含方法LengthFast,它应该计算向量长度的近似值而不使用Math.Sqrt(这似乎是被称为慢)。 LengthFast使用MathHelper.InverseSqrtFast,这是一种非常有趣的方法,可以快速逼近平方根(参见http://www.opentk.com/files/doc/_math_helper_8cs_source.html的第172和196行)。

我创建了一个小型基准测试,调用两次计算100'000'000次,矢量长度介于1到100之间。

在Windows 7 / Intel i7-2600 3.40 GHz上,我得到了:

Length2947 ms

LengthFast4754 ms

在配备MonoTouch的iPad 3上,我得到了:

Length51575 ms

LengthFast41252 ms

所以,LengthFast在英特尔CPU上慢得多,在iPad的ARM上稍快一点。

对此有何解释?这是英特尔CPU能够“原生”计算平方根的结果(不使用软件近似值)吗? LengthFast不应该总是更快,至少是一点点吗?

2 个答案:

答案 0 :(得分:3)

所有Math成员都非常快。不要试图加速.NET数学代码。在ARM处理器上它可能更快,因为ARM处理器上的相同实现需要一些缺少的X86 / X86_64命令,因此代码是不同的。

答案 1 :(得分:1)

如果你看一下LengthFast的来源,它与Quake 3中的那个基本相同。

该算法针对x86指令进行了优化,而不是针对ARM指令。据记载,这种算法在ARM上实际上要慢得多:

http://omcfadde.blogspot.com/2011/02/math-function-micro-optimization.html

  

显然可以看出,这种微优化对x86和x86_64来说非常出色。不要在ARM上试试;它比仅仅采用1.0 / sqrt(x)

的命中要慢得多

修改

原来我把它向后看了......可能是JIT弄乱了你的时间。在进入定时循环之前尝试调用LengthLengthFast一次,以确保两个方法和MathHelper类都被初始化和JITted。它不应该产生那么大的差异,但它是一个起点。 MonoTouch没有JIT,所以它仍然是一个因素。