[Mono-dev] Optimising code breaks maths

Alan McGovern alan.mcgovern at gmail.com
Sun Jan 28 06:51:29 EST 2007


Sorry,

Forgot to add this is with MS.NET (so csc).

Alan

On 1/28/07, Alan McGovern <alan.mcgovern at gmail.com> wrote:
>
> Hi,
>
> While NUniting for Mono.XNA i came across a problem i have no real idea
> how to fix. The problem appears when i compile in "Release" mode with
> optimisations enabled. For example, when i coded a method which calculates
> the 8 corners of a cube when given the 6 sides of the cube, i get completely
> different answers as my result when i compile in release as opposed to
> debug.
>
> What i assume is happening is that the math routines are being optimised,
> which is resulting in the floating point multiplications and divisions being
> moved around thus making the calculation more inaccurate. From my NUnit
> tests debug mode gives me a result of ~0.19 whereas Release mode would give
> a result of 0.125. That's a 30% difference!
>
> Does anyone have any advice on how to code the methods to reduce the
> impact of the optimiser? Or should i just disable optimisations altogether,
> although I'd assume that wouldn't be advisable for performance reasons.
>
> For example, this is what is currently in SVN:
>
>         *private* *static* Vector3 IntersectionPoint(*ref* Plane a, *ref* Plane b, *ref* Plane c)
>         {
>             Vector3 v1, v2, v3;
>             *float* f = -Vector3.Dot(a.Normal, Vector3.Cross(b.Normal, c.Normal));
>
>             v1 = (a.D * Vector3.Cross(b.Normal, c.Normal)) / f;
>             v2 = (b.D * Vector3.Cross(c.Normal, a.Normal)) / f;
>             v3 = (c.D * Vector3.Cross(a.Normal, b.Normal)) / f;
>
>             Vector3 vec = *new* Vector3(v1.X + v2.X + v3.X, v1.Y + v2.Y + v3.Y, v1.Z + v2.Z + v3.Z);
>             *
> return* vec;
>         }
>
> If i change to the following (mathmatically identical form) i end up with a different (more accurate) answer:
>
>         *private* *
> static* Vector3 IntersectionPoint(*ref* Plane a, *ref* Plane b, *ref* Plane c)
>         {
>             Vector3 v1, v2, v3;
>             *float* f = -1 / Vector3.Dot(a.Normal, Vector3.Cross(b.Normal, c.Normal));
>
>             v1 = (a.D * Vector3.Cross(b.Normal, c.Normal));
>             v2 = (b.D * Vector3.Cross
> (c.Normal, a.Normal));
>             v3 = (c.D * Vector3.Cross(a.Normal, b.Normal));
>
>             Vector3 vec = *new* Vector3(v1.X + v2.X + v3.X, v1.Y + v2.Y + v3.Y, v1.Z + v2.Z + v3.Z);
>             *return* vec / f;
>         }
>
> However the results of both methods change depending on whether i'm in debug or release mode, which just isn't good.
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.ximian.com/pipermail/mono-devel-list/attachments/20070128/ee7bf296/attachment.html 


More information about the Mono-devel-list mailing list