Maybe I have a solution of linux floating point problem
Moderator: Moderators
Maybe I have a solution of linux floating point problem
1.The problem may be in different calculation order:
Does somebody want to do the hard work and change all the souce code and put "(" and ")" in each floating point formula.
2.The problem is different accuracy:
a)Problem can be 80 bit format for better accuracy in internal calculations in floating point unit of proccessor:
Calculations are in one of the OS saved in memory and restored in processor register again. Something like that,
Maybe If each operation would be a different expression(y=a+b*c; -->s=b*c;y=s+a; ), would work. But I dont think so.
Another solution is:
For each operation we have to write function. This can be made in easy way by making it with aritmetric-logic operations. If it is too much floating point operations for this synchronisation, processor will not be able to do so much work because it wont use floating point unit. How much is too much? It depends of the percent synchronisational dependent floating point operation in the whole game and CPU ussage.
b)Problem may be 32 bit or 64 bit floating point fomat.
This can checked with Ansi C function sizeof(name of the type).
I dont know much about the concept of the game. So I can be wrong about the solutions.
Does somebody want to do the hard work and change all the souce code and put "(" and ")" in each floating point formula.
2.The problem is different accuracy:
a)Problem can be 80 bit format for better accuracy in internal calculations in floating point unit of proccessor:
Calculations are in one of the OS saved in memory and restored in processor register again. Something like that,
Maybe If each operation would be a different expression(y=a+b*c; -->s=b*c;y=s+a; ), would work. But I dont think so.
Another solution is:
For each operation we have to write function. This can be made in easy way by making it with aritmetric-logic operations. If it is too much floating point operations for this synchronisation, processor will not be able to do so much work because it wont use floating point unit. How much is too much? It depends of the percent synchronisational dependent floating point operation in the whole game and CPU ussage.
b)Problem may be 32 bit or 64 bit floating point fomat.
This can checked with Ansi C function sizeof(name of the type).
I dont know much about the concept of the game. So I can be wrong about the solutions.
TVO and I did some testing and we currently hold the following 2 theorys
1. the heightmap causes sync problems
2. buildtime differences cause economy problems
We played several games and the x positions were exactly the same for specific units. Also of note was the fact that some of the de-syncs came back into "sync" after a period of time.
1. the heightmap causes sync problems
2. buildtime differences cause economy problems
We played several games and the x positions were exactly the same for specific units. Also of note was the fact that some of the de-syncs came back into "sync" after a period of time.
@memarko I think problems can be even more complex
For example in Visual Studio
is not equivalent (under certain flags, optimizations and value of b) to
(I have found this while searching between something very similar to Spring problems)
Another problem would be the implementation of mathematical functions like sin,cos and etc. If by chance on one compiler the result is rounded and on the other is floored.... the final result will be very slightly different.
About 1) I think the order of operation is common to VC/gcc, so paranthesis would be of no use.
About 2) b) I think that sizes for float and double are 4 and 8. (now I have only gcc to test)
For example in Visual Studio
Code: Select all
void f(double b) {
double a = (float)b;
Code: Select all
void f(doube b) {
float t = (float)b;
double a = t;
Another problem would be the implementation of mathematical functions like sin,cos and etc. If by chance on one compiler the result is rounded and on the other is floored.... the final result will be very slightly different.
About 1) I think the order of operation is common to VC/gcc, so paranthesis would be of no use.
About 2) b) I think that sizes for float and double are 4 and 8. (now I have only gcc to test)
Re: Maybe I have a solution of linux floating point problem
This won't solve it. If the compiler executes the operations in a different order, putting "(" ")" around it won't help (if it would help, the compiler is broken).memarko wrote:1.The problem may be in different calculation order:
Does somebody want to do the hard work and change all the souce code and put "(" and ")" in each floating point formula.
We're aware of these possibilities (AMD64 has 64 bit internal FPU accuracy, i386 80 bit).memarko wrote:2.The problem is different accuracy:
a)Problem can be 80 bit format for better accuracy in internal calculations in floating point unit of proccessor:
Calculations are in one of the OS saved in memory and restored in processor register again. Something like that,
Maybe If each operation would be a different expression(y=a+b*c; -->s=b*c;y=s+a; ), would work. But I dont think so.
We (me and greenail) already tested several different configurations and options like -mfpmath=387 to generate 387 fpu instructions on amd64 (which by default uses SSE) and -ffloat-store to write and read back floats to memory after each operation. Every combination we tried had sync errors.
The last solution you give there^^ wouldn't work either because the compiler (with optimisations) would probably generate exactly the same code for both cases.
What do you mean exactly?memarko wrote:Another solution is:
For each operation we have to write function. This can be made in easy way by making it with aritmetric-logic operations. If it is too much floating point operations for this synchronisation, processor will not be able to do so much work because it wont use floating point unit. How much is too much? It depends of the percent synchronisational dependent floating point operation in the whole game and CPU ussage.
Note that this doesn't have to be super difficult because you can make a CFloat classs and overload all operators +-/* etc.
Same applies for fixed point (about the class).
I don't know about windows 64 bit, but gcc 64 bit has same size for float and double types. I doubt this is different on windows.memarko wrote: b)Problem may be 32 bit or 64 bit floating point fomat.
This can checked with Ansi C function sizeof(name of the type).
Thanks for your help anywaymemarko wrote:I dont know much about the concept of the game. So I can be wrong about the solutions.
That's called fixed point arithmetic.FrantzX wrote:We could just choose a precision to our floats (ie number of zeros after the demical point) as use intergal numbers.
example
1.86f / 3.45f = 0.53913043478260869565217391304348
18600 / 34500 =53.913043478260869565217391304348 --> 54
It is a serious solution but we need to carefully research the necessary range and precision, because in general, both are much smaller for fixed point numbers than for floating point numbers. (overflows and underflows are a serious problem for fixed point arithmetic)
To insure cross-platform consistancy with floatpoint operations you must make sure the floatpoint control word is the same on all machines. this controls basicly everything about how the floatpoint engine in the CPU operates and is a part of the IEEE spec on floatpoint handling(well mostly)
The default value depends on what compiler, so you must set it your self to some value.
Keep the floatpoint values in the same data type. single -> double -> single conversions will lose information which is machine dependant on how it happens due to minor rounding errors. Dont to it.
The default value depends on what compiler, so you must set it your self to some value.
Keep the floatpoint values in the same data type. single -> double -> single conversions will lose information which is machine dependant on how it happens due to minor rounding errors. Dont to it.
I think spring already sets it, but maybe it was platform dependent or something. I'll take a better look later.To insure cross-platform consistancy with floatpoint operations you must make sure the floatpoint control word is the same on all machines. this controls basicly everything about how the floatpoint engine in the CPU operates and is a part of the IEEE spec on floatpoint handling(well mostly)
The default value depends on what compiler, so you must set it your self to some value.
This may be the cause of the game going out of sync in M/E long before anything else. I may do a test with all doubles in M/E code replaced by floats...Keep the floatpoint values in the same data type. single -> double -> single conversions will lose information which is machine dependant on how it happens due to minor rounding errors. Dont to it.
Here's an idea, although it may not be the best. Why not let the clients just simply be a 'close enough' simulator. Have the server be the authority and send out "key frames" which basically resync the clients, every say, 100 game ticks. Now what will happend is sync errors all the time, with a resync every x ticks, the server being the final authority and being the true simulator. That said, the added bandwidth, and the fact that the server's compiler/CPU will determine accuracy are the downside. Upside, you don't have to look for sync errors, you expect them, so you simply know to always grab whatever the sever sends every x game ticks. Also don't have to worry about what OS/compiler/options were specified, simply compile and play.
Dono how much change this sort of thing would require, but I'm assuming you could use code in unsynced data to transmit the data stored in synced. Just a thought ;p
Dono how much change this sort of thing would require, but I'm assuming you could use code in unsynced data to transmit the data stored in synced. Just a thought ;p
You will have to.Tobi wrote:Something like continuously resyncing the units going out of sync might be a solution tho, and if it works, I think it is the perfect solution.
Given 2 floatpoint values (float a,b), and preforming arbitary operations on them every frame in a consistant and repeating pattern, the final value at any given time will not the same on 2 differemt machines due to machine dependant rounding of the lowend bits.
You must have some form of resync frames