Hi,
I've tried to build Wormux using a Fixed point class instead of double.
This Fixed point class comes from: http://www.trenki.net/content/view/17/37/
Here are 2 patches to play with this libraries.
Unfortunately, it does not build, because it lacks function for atan and
acos, and I'm definitely unable to write such functions ;)
Regards,
Matt (gentildemon)
Le 11/02/2010 21:28, Matthieu Fertré a écrit :
Hi,
Le 10/02/2010 23:52, Florian Köberle a écrit :
Hello Matthieu
first thank you for gathering the information together.
I like option (b) most. It keeps the code simple and requires only a few
small steps to implement:
1. Change the build process to use streflop
2. Add the line "streflop_init<Double>" to the main.cpp file
3. Replace all occurrences of "float" and "double" with Double
4. Search for includes of<math.h> and replace it with a include
of"streflop.h" and declare that we use the streflop namespace.
Unfortunately, it may be not that easy too according to the 'Notes' on
streflop: "The compiler must not assume strict aliasing. For g++
optimization levels 2 and 3, this assumption is unfortunately the
default.". At least, it gives which gcc flags should be used. But, I'm
just reading the Notes deeper : "This also means you cannot reliably use
this library with gcc on systems where only sse (but not sse2) is
present, like some athlon-xp cores.". This is really sad, because I
don't think we should drop support for such CPU. On the other point, I
agree with you that is seems the best choice. I'm looking to find
another similar library.
You have convinced me that option (a) is as good as impossible to
implement in C/C++.
I totally agree with that point :)
Option (c) seems to be quite tricky to me. The main problem is that
locally games stay synchronous for me and I guess it will be the same
for any other developer which doesn't own two machines. So how do you
want to find out that your resynchronization works? One idea to test it
locally would be VMs but I don't know if they are fast enough if they
simulate another architecture.
Yea, that's a problem :-/
Another option (d), which can also be combined with (a) and (b) is to do
a calculation test which results in a hash of multiple calculation
results. That hash gets then used to determine if a player can play with
another player without a loss of synchronization.
For example would then Wormux ask the index server for games which are
compatible to Wormux 0.9.1 and contain no player with a hash different
to 42251060023612167. Games hosted by headless servers are visible to
all players until a player joins with a specific hash.
In theory option (d) should not be necessary if we implement option (b)
but to catch cases where people compile Wormux wrongly it would be a
nice to have.
I mostly agree with Kurosu. I'm pretty unsure that we can not find one
particular computation that is able to really test the difference
between compiler. Just because sometimes the rounding difference comes
from an optimization such as a loop unrolling.
Regards,
Matt (gentildemon)
Best regards,
Florian
Matthieu Fertré wrote:
Hi,
Floating points operations are not deterministic. That means that the
same computation can give different results because it has been built
with different compilers, with different options. But even running the
same binary on a different CPU may give you different results : by
default, x86 uses 80 bits internal precision while x86_64 uses 64 bits
internal precision, there may have differences in the mathematic library
installed on different systems. You can find some explanations here for
instance [1].
There is no good way to make portable code (remember that Wormux runs on
x86, x86_64, sparc, arm, ...) making deterministic computation.
In fact, there are merely 3 solutions :
a/ force operations precision in a portable way, but it is not that
easy. [2]
b/ do not use floating points operation at all. That means relying of
fixed point integers or using a deterministic floating point library
such as streflop [3]
c/ support non deterministic computation. That means that we have to
resync from times to times. This is how some other games do [4], of
course, we are not the first to face the problem. This is how it works
before Wormux 0.9.0 but it was far from perfect since it was hiding some
bugs (mostly due to bad use of random generator).
From my point of view, we have to re-add synchronizations, at least in
release mode. Anyway, what has been done for 0.9.0 was useful and we
must find way to not hide bugs with synchronization.
Regards,
Matt (gentildemon)
[1]
http://blogs.msdn.com/shawnhar/archive/2009/03/25/is-floating-point-math-deterministic.aspx
[2] http://www.christian-seiler.de/projekte/fpmath/
[3]
http://nicolas.brodu.numerimoire.net/en/programmation/streflop/index.html
[4] http://springrts.com/wiki/Syncing_System
_______________________________________________
Wormux-dev mailing list
Wormux-dev@gna.org
https://mail.gna.org/listinfo/wormux-dev