5

浮動小数点算術演算で異なる CPU で異なる結果が得られる可能性はありますか? CPU とは、x86 と x64 のすべてを意味します。そして、異なる結果とは、重要度の低いビットが1つだけ異なる場合でも..異なるマシンで同じ入力に対応するまったく同じ結果を得ることが不可欠なプロジェクトで浮動小数点演算を使用できるかどうかを知る必要があります。

編集: c++ タグを追加しました。
また、明確にするために、再現可能な結果のランタイムが必要です。異なるコンパイルで同じ結果が得られるとは思いません。

4

2 に答える 2

9

ゲーム業界では、これは決定論的ロックステップ と呼ばれ、クライアントとサーバーが物理オブジェクト (プレイヤー、発射物、変形可能な地形など) の状態について一致している必要があるリアルタイム ネットワーク ゲームでは非常に重要です。

Glenn Fiedler のFloating Point Determinismに関する記事によると、その答えは「かなり足を引きずっているかもしれません」です。同じアーキテクチャで同じバイナリを実行し、基本的な浮動小数点よりも明確に指定されていない機能の使用を制限すると、同じ結果が得られますそれ以外の場合、別のコンパイラを使用するか、コードで SSE または 80 ビット浮動小数点を使用できるようにすると、結果は実行可能ファイルやマシンによって異なります。

Yosef Kreinin の推奨事項:

  • アセンブラー出力をスキャンして代数的最適化を行い、ソース コードに適用します。
  • 融合乗加算およびその他の高度な命令 (sin三角関数など) を抑制します。
  • SSEまたはSSE2を使用するか、FPU CSRを64ビットに設定します。(はい、これは Glenn Fiedler の推奨事項と矛盾します。)

そしてもちろん、複数の異なるマシンでコードをテストしてください。中間出力のハッシュを取得するため、シミュレーションが分岐している場所と時期を正確に知ることができます。

于 2012-08-14T13:30:39.477 に答える
4

動的にリンクされたライブラリを呼び出すと、プロセッサごとに異なるコードが得られる場合があります。(たとえば、Mac OS X の Accelerate ライブラリは、プロセッサごとに異なるルーチンの実装を使用します。)

ただし、プロセッサー・モデルに基づいてディスパッチせず、同一の入力 (浮動小数点モードまたは浮動小数点に影響を与える可能性のあるその他のグローバル状態に加えられた変更を含む) を持つ同一の実行可能イメージ (すべてのライブラリーを含む) を使用すると、プロセッサーはすべての基本的な浮動小数点演算 (加算、減算、乗算、除算、比較、変換) で同じ結果が得られます。

逆平方根推定命令など、特定の演算は、異なるプロセッサで同一の結果を返すように完全に指定されていない場合があります。

コンパイラによる最適化、融合乗加算、SSE/SSE2/FPU の使用に関する ecatmur の回答で言及されている懸念は、同一のバイナリには適用されません。これらの懸念は、異なるコンパイル (異なるスイッチ、異なるターゲット プラットフォーム、異なるコンパイラ バージョン) が異なるコードを生成する可能性がある場合にのみ適用されます。さまざまなコンパイルを除外したため、これらの懸念は関係ありません。

32 ビット ターゲット (i386) と 64 ビット ターゲット (x86_64) の両方をビルドする場合、2 つの実行可能イメージを (1 つの「ファット」ファイルで) 作成することになり、異なるコンパイラ製品に関する懸念が適用されます。

于 2012-08-14T16:17:24.180 に答える