Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is Clang more deterministic than GCC across platforms?

I'm considering the feasibility of programming a multi-user RTS game (partly) in C++. What I quickly discovered, is that one hard requirement is that the game simulation must be fully deterministic to the very last bit across the server and all clients, to be able to limit the network communication to the user input, and not the game state itself. Since everyone has a different computer, this seems like a hard problem.

So, is there some "magic" way of getting the C++ compiler to create an executable that will be fully deterministic across Linux (the server), Windows and Mac? I think the two main OSS C++ compilers are GCC and Clang, so I was wondering if one performs better than the other in this regard.

I would also be interested in any test-suite that could be used to validate C++ determinism.

[EDIT] By deterministic, I meant that the compiled program, given the same initial state, and the input in the same order, will always produce the same output, on any platform where it runs. So, also across the network. Consistent sounds like an appropriate definition of this behavior to me, but I'm not a native speaker, so I might misinterpret the exact meaning.

[EDIT#2] While discussions about whether determinism/consistency matters, and whether I should aim for that in a game engine, and how big a problem it generally is in C++, is quite interesting, it does not in any way actually answer the question. So far, no one had any fact telling me if I should use Clang or GCC to get the most reliable/deterministic/consistent results.

[EDIT#3] It just occurred to me that there IS a way to get exactly the same result in C++ as in Java. One has to take an open source implementation of the JVM, and extract the code that implements the operators and mathematical functions. Then you turn it into a stand-alone library and call inlineable functions in it, instead of using operators directly. It would be a pain to do by hand, but if the code is generated, then it's a perfect solution. Maybe that could even be done with classes and operator overloading, so it looks natural as well.

like image 751
Sebastien Diot Avatar asked Jul 10 '11 11:07

Sebastien Diot


1 Answers

Since everyone has a different computer, this seems like a hard problem.

It's not. Really, this kind of networking is quite simple, so long as you don't do anything that is undefined by the specification. IEEE-754 is very clear on exactly how floating-point math is to be done, how rounding is to be done, etc, and it is implemented identically across platforms.

The biggest thing you need to not do is rely on SIMD CPU instructions in code that needs to be deterministic (note: this is physics, AI, and such: game state. Not graphics, which is where you need SIMD). These kinds of instructions play fast-and-loose with the floating-point rules. So no SIMD in your game code; only in the "client" code (graphics, sound, etc).

Also, you need to make sure that your game state doesn't depend on things like the time; each game state clock tick should be a fixed time interval, not based on the PC's clock or anything of that nature.

Obviously, you should avoid any random function you don't have the code to. But again, only for your main gameplay loop; the graphics stuff can be client-specific, since it's just visuals and doesn't matter.

That is pretty much it, as far as keeping the two game states in sync. The compiler you use isn't going to be a big issue for you.

Note that StarCraft and StarCraft II use this as the basis of their networking model. They both run on Macs and PCs, and both can play against each other. So it's very possible, and doesn't require Clang.

Though if you like Clang, you should use it. But that should be because you like it, not for networking.

like image 192
Nicol Bolas Avatar answered Sep 28 '22 07:09

Nicol Bolas