All Math
members are really fast. Don't try to speed up .NET math code. On a ARM processor it may be faster because there are some missing X86/X86_64 commands which are required for the same implementation on a ARM processor, so the code is different.
OpenTK's Vector2.Length is twice as fast as Vector2.LengthFast
-
29-11-2021 - |
Question
The OpenTK
libraries, and with them, MonoTouch and MonoDroid, contain the method LengthFast
, which should calculate an approximation of a vector's length without the use of Math.Sqrt
(which seems to be known as slow). LengthFast
uses MathHelper.InverseSqrtFast
, a quite interesting method which should give a fast approximation of the square root (see lines 172 and 196 of http://www.opentk.com/files/doc/_math_helper_8cs_source.html).
I created a small benchmark which invokes both calculations 100'000'000
times, with vector lengths between about 1 and 100.
On Windows 7 / Intel i7-2600 3.40 GHz, I got:
Length
: 2947 ms
LengthFast
: 4754 ms
On an iPad 3 with MonoTouch, I got:
Length
: 51575 ms
LengthFast
: 41252 ms
So, LengthFast
is much slower on the Intel CPU, on the iPad's ARM it is slightly faster.
Any explanation for this? Is that the result of the Intel CPU being able to calculate the square root 'natively' (without the use of software approximation)? Shouldn't LengthFast
be always faster, at least a little bit?
Solution
OTHER TIPS
If you look at the source of LengthFast
it's basically the same bit hack as the one in Quake 3.
The algorithm is optimized for x86 instructions, not so much for ARM instructions. It's been documented that this algorithm is actually quite a bit slower on ARM:
http://omcfadde.blogspot.com/2011/02/math-function-micro-optimization.html
Clearly it can be seen that this micro-optimization is an excellent for x86 and x86_64. Don't try it on ARM; it's far slower than just taking the hit on 1.0 / sqrt(x)
EDIT
Turns out I read it backwards... could be the JIT messing with your timings. Try invoking Length
and LengthFast
once before going into the timed loop to make sure both methods and the MathHelper
class get initialized and JITted. It shouldn't make that big of a difference, but it's a starting point. There's no JIT with MonoTouch, so it's still going to be a factor.