Floating point oddities
Are floating point operations defined to be the same on different processors? In complex scenes using my physics code, I've noticed slight differences in behavior between my G5 and MacBook. Is this an indication that there are weird bugs in my code or is it just a difference in accuracy/precision between processors?
Is it possible to enforce a similar behavior other than reverting to integer math?
Is it possible to enforce a similar behavior other than reverting to integer math?
Scott Lembcke - Howling Moon Software
Author of Chipmunk Physics - A fast and simple rigid body physics library in C.
It's pretty much up to the hardware to handle certain cases. I believe the only way to ensure the same floating point values is to do them in software. (assuming that the software implementations are the same, of course. Definitely not ideal.
I think IEEE 754 is pretty strict in general. There are two things I can think of offhand:
If you're using shortcuts like __fres or __frsqrte, you can expect things to be different even between G3/G4/G5 -- obviously those two instructions don't exist on Intel, but there is an equivalent which you could be using
The other is that the PowerPC has an instruction called "fmadds" (and double-precision version fmadd) which has no analog on Intel. Do this on a PowerPC machine:
If it returns any lines, you can expect to see small differences. Every floating-point instruction is effectively round-to-register-size(calculate-at-extended-precision(operation, inputs)). fmadds does a = b * c + d, so on PowerPC turns out like:
but on Intel it turns out like:
I think there's a way to prevent the compiler from generating fmadd(s) instructions if you care greatly, in which case your PowerPC code will end up looking like:
But it's better to assume that you'll get different results on different processors
If you're using shortcuts like __fres or __frsqrte, you can expect things to be different even between G3/G4/G5 -- obviously those two instructions don't exist on Intel, but there is an equivalent which you could be using

The other is that the PowerPC has an instruction called "fmadds" (and double-precision version fmadd) which has no analog on Intel. Do this on a PowerPC machine:
Code:
otool -tV <path to your exe> | grep fmadd
If it returns any lines, you can expect to see small differences. Every floating-point instruction is effectively round-to-register-size(calculate-at-extended-precision(operation, inputs)). fmadds does a = b * c + d, so on PowerPC turns out like:
Code:
a = round(b * c + d)
but on Intel it turns out like:
Code:
a = b
a = round(a * c)
a = round(a + d)
I think there's a way to prevent the compiler from generating fmadd(s) instructions if you care greatly, in which case your PowerPC code will end up looking like:
Code:
a = round(b * c)
a = round(a + d)
But it's better to assume that you'll get different results on different processors

Yep, I got me lots of them fmadds.
Seriously though, that's annoying as it could make networking or replays difficult between platforms. Fortunately I don't think that I'll be using piles of hundreds of objects in any real game to really accumulate the errors.
Seriously though, that's annoying as it could make networking or replays difficult between platforms. Fortunately I don't think that I'll be using piles of hundreds of objects in any real game to really accumulate the errors.
Scott Lembcke - Howling Moon Software
Author of Chipmunk Physics - A fast and simple rigid body physics library in C.
For networking, you'll always have an authoritative world-view in the server, so as long as it sends absolute positions/orientations for objects reasonably regularly, the error should always be small enough to be irrelevant.
For replays, you can just take the same approach -- store keyframes on a regular basis to ensure that errors don't compound.
For replays, you can just take the same approach -- store keyframes on a regular basis to ensure that errors don't compound.
Skorche Wrote:Fortunately I don't think that I'll be using piles of hundreds of objects in any real game to really accumulate the errors.
I think even tiny changes can accumulate to large ones over time in a "butterfly effect". I had this happen to me once where I wasnt saving the initial conditions correctly and the playback would look exactly correct for awhile and then slowly drift and then completely break down. It was fun to watch, more fun than the actual game unfortunately.
Reminds me of the Lorenz weather simulation experiment:
http://www.crystalinks.com/chaos.html
While working on my animations, I quickly discovered that if I didn't normalize my quaternions, it would eventually cause the part of the mesh that's being animated to either implode or explode within 20 seconds or so.

If you want absolute replayability, do as OSC says, and store keyframes.
Also, if you algorithms are upset by a little change in how floating point computations are handled, you might want to revise them to be less susceptible to this kind of thing.
Also, if you algorithms are upset by a little change in how floating point computations are handled, you might want to revise them to be less susceptible to this kind of thing.
DoG Wrote:Also, if you algorithms are upset by a little change in how floating point computations are handled, you might want to revise them to be less susceptible to this kind of thing.
Not like you really have any choice when the positions of the rigid bodies are calculated from the position from the frame before. That and the impulses that are modifying the motion of the bodies are calculated iteratively so one iteration affects all subsequent iterations.
Scott Lembcke - Howling Moon Software
Author of Chipmunk Physics - A fast and simple rigid body physics library in C.
Skorche Wrote:Not like you really have any choice when the positions of the rigid bodies are calculated from the position from the frame before. That and the impulses that are modifying the motion of the bodies are calculated iteratively so one iteration affects all subsequent iterations.You'd have to be a bit more specific as to what differences in the behavior of your app there are on different CPUs, it might be possible to, for example, reduce creep or prevent the simulation from blowing up.
Possibly Related Threads...
Thread: | Author | Replies: | Views: | Last Post | |
3D position of a point in 3D plane having local 2D coordinates of the point | nikito | 3 | 6,815 |
Jul 1, 2010 12:25 PM Last Post: Skorche |