8

iOS 用の Box2D 物理演算を使用したマルチプレイヤー ゲームを開発しています。マルチプレイは相変わらずロックステップ方式。ゲームは物理ワールドを固定タイムリーに更新します。同じ CPU を搭載した iOS デバイス間で同期がずれることはありません。

ただし、Apple A6 チップを搭載した新しい iOS デバイスでテストすると、非同期が発生しました。ログ ファイルを表示すると、desync が非常に高速に発生しているような印象を受けます。これはおそらく、まだ特定できていない浮動小数点演算が原因であると思われます。

ゲームの設計で同期が必要なモジュールは Box2D だけであり、ログによると、すべてのマルチプレイヤー コマンドと入力が非同期ではないことを保証できます。

すべての超越関数を変更しようとしました: sinf、cosf、pow、sqrtf、atan2f を double バージョンに変更しましたが、うまくいきませんでした。

一部のコンパイラ オプションのように、Apple A6 が浮動小数点数を Apple A5 と同じように扱うように強制する方法はありますか?

どんな答えでも本当に感謝します。

4

3 に答える 3

5

多くの数学ライブラリ関数は、A5とA6で異なるアルゴリズムを使用しています。それらが1〜2 ulp以上異なる場合は、バグを見つけた可能性があります。報告してください。それ以外の場合、変動は高品質の数学ライブラリの予想される許容範囲内にある可能性があります。これがなぜそうなのかを垣間見るために、最良の参照は、数年前のmac-games-devメーリングリストへのIanOllmannの電子メールです。 「数学ライブラリはセキュリティツールではありません」、Mac OS Xのコンテキストでこの正確な問題に対処しました。(tl; drバージョンは、一部のゲーム開発者が望んでいる、アーキテクチャ間でビット同一の結果を提供するという目標が、高精度の回答を提供することと根本的に矛盾することです。すべての開発者[および応答性とバッテリー寿命にメリットがあるためユーザー]が望むすべてのアーキテクチャーで可能な限り効率的に;何かを与える必要があり、汎用システムライブラリーの場合は後者が必然的に優先されます)。Appleデベロッパフォーラムは、情報を探すのに適したもう1つの場所です。

于 2012-12-16T23:48:30.483 に答える
3

それは実際には再びNguyen Truong Chungです。

これまでご回答いただきました皆様、誠にありがとうございました。デバッグを続ける道を教えてくれたあなたの回答に本当に感謝しています! 現時点では、非同期の理由はなんとなくわかりましたが、具体的な解決策はまだありません。私が得た情報をあなたに提供したいと思います。うまくいけば、より多くの洞察を得ることができます。

1. 発見:

cosを使用するこの関数があります。次のようにログを出力しました。

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 は次のように発生しました。

iPad4 の場合: Vector3D::SelfRotateZ(404800d2) bf7ff708、3c8782bc iPhone4 の場合: Vector3D::SelfRotateZ(404800d2) bf7ff709、3c8782bc

2. 再テスト:

話はここで終わりではありません。理由は次のとおりです。

  1. ゲームの開始時に次のコード行を試しました。

{ unsigned int zz = 0x404800d2;

float yy = 0;

memcpy( &yy, &zz, 4 );

const float temp1 = cos( yy );


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

}

  1. 上記のコードを同じ iPhone4 で実行しました。私はこれを手に入れました:bf7ff708

  2. そのコードをゲームの更新ループに入れましたが、得られた結果はループごとにまだ bf7ff708 でした。

  3. さらに何ですか?値 0x404800d2 はゲームの初期化値であるため、ゲームが開始されるたびに、上記の 2 つの desync ラインが常に存在します。

3: 尋問:

そこで、上記のことは忘れて、sin、cos 関数を一時的に、dreamcode.net で見つけた単純な Taylor の実装に置き換えることにしました。desync は発生しなくなりました。

cos 関数は、同じ iPhone 4 (OS バージョン 5) では決定論的でさえないようです。

私の質問は、cos 関数が同じ電話の同じ入力に対して異なる結果を返す理由について説明がありますか? ここでは、入力 0x404800d2 と、bf7ff708 と bf7ff709 という 2 つの異なる出力があります。ただし、単純なコーディングでは結果 bf7ff709 を再現できません。

これを明確に理解するには、OS(浮動小数点版)の数学関数のソースコードが必要だと思います。上記の問題はバグレポートとして十分ですか?

于 2012-12-18T10:02:55.823 に答える
1

それは実際には再びNguyen Truong Chungです。:)

これまでお世話になり、誠にありがとうございました。

cos、sin、sqrt、pow、atan2、atan、asin、acosなどのすべての超越関数を(できるだけ多く)書き直した後、非同期が修正されたことを報告したいだけです。

于 2012-12-19T15:38:21.667 に答える