Question

I am developing a multiplayer game with Box2D physics for iOS. The multiplayer is using lock-step method as usual. The game updates physics world fixed-timely. There is no desync among iOS devices with same CPU.

However, when testing with new iOS devices with Apple A6 chip, desync happened. Viewing my log file gives me the impression that desync happens quite fast and it was probably because of some floating point operation that I could not find out which yet.

I can guarantee that only Box2D is the only module needed to be synchronized in the design of the game, and all mutliplayer commands and inputs are not out-of-sync according to my log.

I have tried changing all transcendental functions: sinf, cosf, pow, sqrtf, atan2f to double version, but without any luck.

Is there any way to force Apple A6 treating floating point numbers as same as Apple A5 like some compiler options?

I will really appreciate any answer.

Was it helpful?

Solution

A number of math library functions use different algorithms on the A5 and A6. If they differ by more than an ulp or two, you may have found a bug; please report it. Otherwise, the variation is likely within the expected tolerances of good-quality math library. For a glimpse into the reasons of why this is so, the best reference is Ian Ollmann's email to the mac-games-dev mailing list several years ago, "the math library is not a security tool", which addressed this exact issue in the context of Mac OS X. (the tl;dr version is that the goal of delivering bit-identical results across architectures, which some game developers want, is fundamentally in conflict with delivering high-accuracy answers as efficiently as possible on all architectures, which all developers [and users, since it benefits responsiveness and battery life] want; something has to give, and for a general-purpose system library the latter necessarily takes priority). The Apple developer forums would be another good place to look for information.

OTHER TIPS

it is actually Nguyen Truong Chung again.

Thank you all very much for your answers so far. I really appreciate your answers, which enlightened me the path to continue debugging! At the moment, I somehow found out the reason of the desync, but without concrete solutions yet. I wish to provide you with information I got, and hopefully I can get some more in-sights.

1. Finding:

I have this function that use cos. I printed the log like this:

void rotateZ( float angle )

{

 if( angle )

 {

      const float sinTheta = sin( angle );

      const float cosTheta = cos( angle );



      // I logged here

      myLog( "Vector3D::SelfRotateZ(%x) %x, %x", *(unsigned int*)&angle, *(unsigned int*)&cosTheta, *(unsigned int*)&sinTheta );



      ....
 }

}

Desync happened like this:

On iPad4: Vector3D::SelfRotateZ(404800d2) bf7ff708, 3c8782bc On iPhone4: Vector3D::SelfRotateZ(404800d2) bf7ff709, 3c8782bc

2. Re-testing:

And the story does not stop here because:

  1. I tried these line of code at the beginning of the game:

{ unsigned int zz = 0x404800d2;

float yy = 0;

memcpy( &yy, &zz, 4 );

const float temp1 = cos( yy );


printf( "%x\n", *(unsigned int*)&temp1;

}

  1. I ran the code above on the same iPhone4, and guess what? I got this: bf7ff708

  2. I put that code in the update loop of the game and the result I got was still bf7ff708 at every loop.

  3. What is more? The value 0x404800d2 is an initialize value of the game, so every time the game starts, the two desync lines above are always present there.

3: The questioning:

So, I decided to forget what happened above, and temporarily replaced sin, cos function with simple Taylor implementations I found on dreamcode.net. The desync no longer happened.

It seems that the cos function is not even deterministic on the same iPhone 4 (OS version 5).

My question is: Do we have an explanation why cos function returns different result for the same input on a same phone? Here I have the input 0x404800d2, and two different outputs: bf7ff708 and bf7ff709. However, I cannot reproduce the result bf7ff709 by simply coding.

I guess I need the source code of math functions of the OS (floating-point version) in order to understand this clearly. Is above problem I found enough as a bug report?

It's actually Nguyen Truong Chung again. :)

Thank you very much for your help so far.

I just want to report that the desync is fixed after I rewrote all transcendental functions like cos, sin, sqrt, pow, atan2, atan, asin, acos, etc. ( as many as possible ).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top