Question: Bit-exact floats on different computers?

Hey.

Has anyone successfully managed to get a perfectly synced up game client where all computers in a networked game did the exact same computations and got the exact same results regardless of hardware/OS/etc with Java? Is strictfp enough to get this? Is it possible to do this between x86 and ARM?

strictfp will do this.

Cas :slight_smile:

Even on ARM and for both floats and doubles? Can I be 100% sure that if I run the exact same deterministic program on both the result will be bitwise exactly the same?

Short of a VM bug, hardware bug, or error in your own code, yes.

Java requires & utilizes only IEEE 754 floating point.
( https://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.2.3 )
FP-strict forces all intermediate values to be constrained to the same precision as the operands.
( https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.4 )

I have yet to run into any problems, but my engine game isn’t super sophisticated yet.

Supreme commander utilized IEEE 754 to achieve determinism. If I recall correctly they had a couple outliers, but the vast majority of players had zero problems.

Yes i have tested this ages ago. It is one of the reasons the base java math class is fairly slow since IEEE 7 whatever is fairly strict and java requires 2ulp accuracy (also Part of IEEE IIRC). It is bit perfect.

In fact we have also done this with C/C++ across quite a wide range of CPUs. But for that you got to get your compiler flags right for each target. It is def much easier to do in java.

People often think that floating point is somehow not deterministic. Not sure why. But outside bugs, it is.

I think because there were subtle differences in implementations on various processors over the last 20 years (f. ex. Intel using 80-bit internals for computation unless you use strictfp). That, and understanding exactly how floats work in all situations is very complicated (I don’t really know myself) and there are better things to do with one’s day.

Cas :slight_smile:

The reason why I thought it wasn’t exact was the ULP requirement. If the result has to be within 2 ULP of the correct result, then technically there are up to 5 possible answers that are all deemed correct. Is there really a requirement that says that all hardware must round all results exactly the same way?

Thanks for all the info everyone!

I’d suggest to avoid the problem. Make your life easier. The server is always right. Mostly send relative information and have client side smoothing. Periodically send absolute information, but not in the same packet for every object. Then you don’t have to care about any compounding of errors due to FP results…it will go away at the next abs-update and it mostly will be unnoticed due to client side smoothing. This also allows different versions of the game to work together as long as the net datamodel hasn’t changed (barring other breaking changes of course).

The problem is that this can lead to very weird situations. An error in one object’s position can cascade out to all nearby object through physics etc, so a huge pile of AI could constantly be pushing each other into the wrong positions if not all of them are updated at once. That would require the server not updating random objects each update, but identifying all touching objects to resync the entire batch. At the same time, we can’t afford to use lock-stepping either since it’s not responsive enough. I’m just scouting my options here, and if floats are reliable enough, then that’s another tool I can use if I need to.

Model the world on the server; model the special effects on the client. If something is critical to the gameplay, the server should be the arbiter. If it’s just eye-candy, let the client do whatever it likes.

Cas :slight_smile:

Seems to me that miniscule mathematical differences should not amount to significant differences in logic. If your world is made of perfectly spherical billiard balls rolling over perfectly flat, frictionless surfaces, the tiny differences quickly add up. But in a real world there is friction and nonrigidity.

KevGlass made a networked game using perfect determinism with strictfp that was a success. I forget which game that was but I found this old discussion about it on google:
http://www.java-gaming.org/index.php?topic=18183.0
[EDIT, found it]: http://www.java-gaming.org/topics/networking-a-dungeon-crawl/10516/msg/83159/view.html#msg83159

My little networked game used Roquen’s approach where the server is always right. But I used a funny setup to update the clients where the server would send an old game world’s state which was then updated to the present by the clients. This happened every few seconds.
There’s some detail about it here:

I wasn’t happy with the end result since there was noticeable frame drop when the big update occurred to get the old server world up to date by applying all of the events and updates. But perhaps it could be refined some more.

I’ll be interested to see how you deal with the networked game problem.

It’s unwise to depend on exact value floats. Even if you believe everyone is doing the same
calculation, compilers can and do change the order of calculations in ways that are permitted by
the normal laws of arithmetic, but which no floating point implementation can actually follow.

Although I generally agree with the first sentence, everything past that is incorrect.

“compilers can and do change the order of calculations”: with specifically known set of rules which are language specific and may depend on programmer specs in code and/or compiler settings.

“in ways that are permitted by the normal laws of arithmetic”: if you mean Z/Zn integers and IEEE spec FP then okay, otherwise no. The only tricky part is FP functions that are not required to be properly rounded. You have to know what they are and not use them for exact computation everywhere.

“but which no floating point implementation can actually follow.” IEEE FP rules aren’t black magic and if you don’t use variable ULP functions and disallow any compiler transforms that change error bound then all computations are bit-exact. That’s one of the main points of the spec in the first place.

… which is exactly what strictfp does, at the occasional expense of a bit of performance here or there :slight_smile: Even so it’s probably going to be quite hard to find bugs in your client when they inexplicably diverge at some point.

Cas :slight_smile:

yeap, but you have to take care with things like “java.Math” functions.

Which functions?

Looking quickly, the follow should all be good of the fp routines:
sqrt,ceil,floor,rint,round,abs,min,max,ulp,signum,copySign,next{Up,Down,After},scalb

Why not just use StrictMath everywhere?

Do some of the Math methods with exactly defined results (e.g. Math.sqrt) get intrinsified?