C#での浮動小数点演算は一貫していますか?できますか?


155

いいえ、これは「なぜ(1 / 3.0)* 3!= 1なのか」という別の質問ではありません。

最近、浮動小数点についてよく読んでいます。具体的には、同じ計算が異なるアーキテクチャまたは最適化設定で異なる結果をもたらす方法です。

これは、リプレイを保存する、または(サーバークライアントではなく)ピアツーピアネットワーク化されたビデオゲームの問題であり、プログラムを実行するたびにすべてのクライアントがまったく同じ結果を生成することに依存します。浮動小数点計算は、異なるマシン(または同じマシンでも!)で劇的に異なるゲーム状態につながる可能性があります。

これは、主に一部のプロセッサ(つまりx86)が倍の拡張精度を使用するため、IEEE-754に「従う」プロセッサの間でも発生します。つまり、80ビットのレジスタを使用してすべての計算を行い、64ビットまたは32ビットに切り捨てて、計算に64ビットまたは32ビットを使用するマシンとは丸めの結果が異なります。

オンラインでこの問題のいくつかの解決策を見てきましたが、すべてC ++ではなくC ++向けです。

  • (Windows)、(Linux?)、または(BSD)をdouble使用して、倍精度拡張モードを無効にします(すべての計算でIEEE-754 64ビットを使用し_controlfp_sます)。_FPU_SETCWfpsetprec
  • 常に同じコンパイラーを同じ最適化設定で実行し、すべてのユーザーが同じCPUアーキテクチャーを持っている必要があります(クロスプラットフォームの遊びはありません)。私の「コンパイラ」は実際にはJITであるため、プログラムを実行するたびに異なる最適化が行われる可能性があります、これは可能ではないと思います。
  • 固定小数点演算を使用しfloatdouble完全に回避します。decimalこの目的のためにSystem.Math機能しますが、はるかに遅くなり、ライブラリ関数のどれもそれをサポートしません。

それで、これはC#の問題でもありますか? (Monoではなく)Windowsのみをサポートする場合はどうなりますか?

もしそうなら、私のプログラムを通常の倍精度で実行させる方法はありますか?

そうでない場合、浮動小数点計算の一貫性保つのに役立つライブラリはありますか?


私はこの質問を見きましたが、すべての回答は、解決策なしで問題を繰り返すか、「無視する」と言っていますが、これはオプションではありません。私は尋ねたgamedev上で同様の質問を回答のほとんどはC ++に向けているように見える(なぜなら観客の)、しかし。
BlueRaja-ダニープフルフフト

1
ない答えが、私はあなたがほとんどのドメインでは、すべての共有状態が決定論的であり、そのせいでの有意なパフォーマンスの低下がないようにあなたのシステムを設計できたよ
driushkin

1
@Peter .netの高速浮動小数点エミュレーションを知っていますか?
CodesInChaos

1
Javaはこの問題の影響を受けますか?
Josh

3
@Josh:Javaにはstrictfpキーワードがあり、すべての計算が拡張サイズではなく、指定されたサイズ(floatまたはdouble)で実行されます。ただし、JavaにはまだIEE-754サポートに関する多くの問題があります。非常に(非常に)非常に少数のプログラミング言語がIEE-754を適切にサポートしています。
ポルジュ2011

回答:


52

.netで通常の浮動小数点を決定論的にする方法がわかりません。JITterは、異なるプラットフォーム(または.netの異なるバージョン間)で異なる動作をするコードを作成することができます。したがってfloat、確定的.netコードで通常のを使用することはできません。

私が検討した回避策:

  1. C#でFixedPoint32を実装します。これはそれほど難しくありませんが(実装は半分完成しています)、値の範囲が非常に狭いため、使用するのが面倒です。オーバーフローしたり、精度を失ったりしないように、常に注意する必要があります。最後に、これは整数を直接使用するより簡単ではないことがわかりました。
  2. C#でFixedPoint64を実装します。これはかなり難しいと思いました。一部の操作では、128ビットの中間整数が役立ちます。しかし、.netはそのようなタイプを提供していません。
  3. カスタム32ビット浮動小数点を実装します。これを実装する場合、BitScanReverse組み込み関数がないため、いくつかの問題が発生します。しかし、現在私はこれが最も有望な道だと思います。
  4. 数学演算にはネイティブコードを使用します。すべての数学演算でのデリゲート呼び出しのオーバーヘッドを引き起こします。

32ビット浮動小数点演算のソフトウェア実装を開始しました。2.66GHz i3で毎秒約7,000万回の加算/乗算を実行できます。 https://github.com/CodesInChaos/SoftFloat。明らかにそれはまだ非常に不完全でバグが多いです。


2
BigIntegerは「無制限」のサイズの整数で利用できますが、ネイティブのintほど高速ではありません。そのため、.NETはそのような型を提供します(F#用に作成されていますが、C#で使用できます)
Rune FS

もう1つのオプションは、.NET用のGNU MPラッパーです。これは、GNU Multiple Precision Libraryのラッパーであり、「無限」の精度の整数、有理数(分数)、および浮動小数点数をサポートします。
Cole Johnson

2
これらのいずれかを実行する場合は、decimalはるかに簡単なので、最初に試してみるのもよいでしょう。目前のタスクにとって遅すぎる場合にのみ、他のアプローチを検討する価値があります。
Roman Starkov、2015

浮動小数点が決定論的である特別なケースについて学びました。説明:乗算/除算の場合、FP数の1つが2の累乗(2 ^ x)である場合、有効/仮数は計算中に変化しません。指数のみが変化します(ポイントが移動します)。したがって、丸めは起こりません。結果は確定的です。
ジグザグ

例:2 ^ 32のような数値は(指数:32、仮数:1)として表されます。これに別のfloat(exp、man)を掛けると、結果は(exp + 32、man * 1)になります。除算の場合、結果は(エキスポ-32、人* 1)です。仮数に1を掛けても仮数は変更されないため、ビット数は関係ありません。
ジグザグ

28

C#仕様(§4.1.6浮動小数点型)では、結果よりも高い精度を使用して浮動小数点計算を実行できます。ですから、いいえ。これらの計算を.Netで直接決定論的に行うことはできないと思います。他の人はさまざまな回避策を提案したので、それらを試すことができました。


9
コンパイルされたアセンブリを配布する場合、C#の仕様はそれほど重要ではないことに気づきました。ソースの互換性が必要な場合にのみ重要です。本当に重要なのはCLR仕様です。しかし、その保証はC#の保証と同じくらい弱いと確信しています。
CodesInChaos、2011

double操作が不要なビットを取り除き、一貫した結果が得られるたびにキャストしませんか?
IllidanS4がモニカに2016

2
@ IllidanS4一貫した結果が保証されるとは思いません。
2016

14

次のページは、そのような操作の絶対的な移植性が必要な場合に役立ちます。浮動小数点演算をエミュレートするソフトウェアを含む、IEEE 754標準の実装をテストするためのソフトウェアについて説明します。ただし、ほとんどの情報はおそらくCまたはC ++に固有のものです。

http://www.math.utah.edu/~beebe/software/ieee/

定点に関する注意

2進固定小数点数は、4つの基本的な算術演算から明らかなように、浮動小数点の代わりとしても機能します。

  • 足し算と引き算は簡単です。これらは整数と同じように機能します。足すか引くか!
  • 2つの固定小数点数を乗算するには、2つの数値を乗算してから、定義された数の小数ビットを右にシフトします。
  • 2つの固定小数点数を除算するには、被除数を定義された小数ビットの数だけ左にシフトし、除数で除算します。
  • このペーパーの第4章には 2進固定小数点数の実装に関する追加のガイダンスがあります。

2進固定小数点数は、int、long、BigIntegerなどの整数データ型と、CLSに準拠しない型のuintおよびulongに実装できます。

別の回答で提案されているように、テーブル内の各要素が2進固定小数点数であるルックアップテーブルを使用して、サイン、コサイン、平方根などの複雑な関数を実装できます。ルックアップテーブルの精度が固定小数点数よりも小さい場合は、ルックアップテーブルの精度の半分を入力に追加して、入力を丸めることをお勧めします。

// Assume each number has a 12 bit fractional part. (1/4096)
// Each entry in the lookup table corresponds to a fixed point number
//  with an 8-bit fractional part (1/256)
input+=(1<<3); // Add 2^3 for rounding purposes
input>>=4; // Shift right by 4 (to get 8-bit fractional part)
// --- clamp or restrict input here --
// Look up value.
return lookupTable[input];

5
これは、sourceforgeやgithubなどのオープンソースコードプロジェクトサイトにアップロードする必要があります。これにより、見つけやすく、投稿しやすくなり、履歴書を書きやすくなります。また、いくつかのソースコードのヒント(無視して構いません):定数のconst代わりに使用しstaticて、コンパイラーが最適化できるようにします。静的関数よりもメンバー関数を優先します(たとえば、のmyDouble.LeadingZeros()代わりに呼び出すことができますIntDouble.LeadingZeros(myDouble))1文字の変数名を避けるようにしてください(MultiplyAnyLengthたとえば、9である場合、追跡が非常に難しくなります)
BlueRaja-Danny Pflughoeft

使用して注意してくださいuncheckedとのような非CLS準拠の種類ulonguintスピードのためになど、 -彼らはそうめったに使用されているので、JITは積極的として、それらを最適化しない、それらを使用して、実際にできるように遅くなるように、通常のタイプを使用するよりもlongしてint。また、C#には演算子のオーバーロードがあり、このプロジェクトから大きなメリットが得られます。最後に、関連する単体テストはありますか?それらの小さなもの、驚くべき仕事ピーターに加えて、これは途方もなく印象的です!
BlueRaja-Danny Pflughoeft、

コメントありがとうございます。コードで単体テストを実行します。ただし、かなり広範ですが、現時点ではリリースするには広すぎます。複数のテストを簡単に作成できるように、単体テストヘルパールーチンも作成しています。完了したらコードをJavaに変換する計画があるので、ここではオーバーロードされた演算子を使用しません。
Peter O.11年

2
面白いのは、私があなたのブログに投稿したとき、ブログがあなたのものであることに気付かなかったということです。私はgoogle +を試すことを決めたばかりで、C#のスパークでそのブログエントリを提案しました。それで、「二人でそんなことを同時に書き始めるなんて、なんと驚くべき偶然なのだろう」と思いました。しかし、もちろん同じトリガーがありました:)
CodesInChaos '23 / 07/23

1
なぜこれをJavaに移植する必要があるのですか?Javaはすでにを介して確定的浮動小数点演算を保証していstrictfpます。
アンチモン2013

9

これはC#の問題ですか?

はい。アーキテクチャが異なると心配することはほとんどありません。フレームレートが異なるなど、フロート表現の不正確さが原因で偏差が発生する可能性があります-たとえそれらが同じ不正確であっても(たとえば、1つのマシンのGPUが遅いことを除いて、同じアーキテクチャ)。

System.Decimalを使用できますか?

できない理由はありませんが、犬が遅いのです。

プログラムを強制的に倍精度で実行する方法はありますか?

はい。CLRランタイムを自分でホストします。そして、CorBindToRuntimeExを呼び出す前に、すべての必要な呼び出し/フラグ(浮動小数点演算の動作を変更する)をC ++アプリケーションにコンパイルします。

浮動小数点計算の一貫性を保つのに役立つライブラリはありますか?

私が知っていることではありません。

これを解決する別の方法はありますか?

以前にこの問題に取り組んだことがあるのですが、アイデアはQNumbersを使用することです。それらは固定小数点である実数の形式です。ただし、base-10(10進数)の固定小数点ではなく、base-2(2進数); このため、それらの数学プリミティブ(add、sub、mul、div)は、単純なbase-10固定小数点よりもはるかに高速です。特にn両方の値が同じ場合(あなたの場合は同じです)。さらに、これらは一体型であるため、すべてのプラットフォームで明確な結果が得られます。

フレームレートもこれらに影響を与える可能性があることに注意してください。フレームレートはそれほど悪くはなく、同期ポイントを使用して簡単に修正できます。

QNumbersでより多くの数学関数を使用できますか?

はい、これを行うには小数を往復します。さらに、trig(sin、cos)関数のルックアップテーブルを実際に使用する必要があります。これらは実際には異なるプラットフォームで異なる結果をもたらす可能性があるため、正しくコーディングすればQNumbersを直接使用できます。


3
問題となっているフレームレートで何を話しているのかわからない。明らかに、更新レートを固定したいと思うでしょう(たとえば、こちらを参照してください)。これは、display-framerateと同じかどうかに関係なく、無関係です。誤差がすべてのマシンで同じである限り、問題はありません。3つ目の答えがまったくわかりません。
BlueRaja-Danny Pflughoeft、2011

@BlueRaja:回答「プログラムを倍精度で実行させる方法はありますか?」非常に複雑な共通言語ランタイム全体を再実装するか、ユーザーshelleybutterflyの回答に示唆されているように、C#アプリケーションからC ++ DLLへのネイティブ呼び出しを使用することになります。私の答えにほのめかしたように、単にバイナリ固定小数点数として「QNumbers」を考える(私は今と呼ばれる「QNumbers」である進固定小数点数を見てまでではなかった。)
ピーターO.を

@Pieter O.ランタイムを再実装する必要はありません。会社で作業しているサーバーは、CLRランタイムをネイティブC ++アプリケーションとしてホストします(SQL Serverもホストします)。グーグルCorBindToRuntimeExをお勧めします。
ジョナサンディキンソン

@BlueRajaそれは問題のゲームに依存します。すべてのゲームに固定フレームレートステップを適用することは実行可能なオプションではありません。これはFPSなどでは受け入れられません。
ジョナサンディキンソン

1
@ジョナサン:これは、入力のみを送信するピアツーピアゲームの唯一の問題です。これらの場合、更新レートを固定する必要あります。ほとんどのFPSはこのように機能しませんが、更新レートが固定されているFPSは必ずしもありません。この質問を見る
BlueRaja-Danny Pflughoeft 2011

6

この少し古いMSDNブログエントリによると、JITは浮動小数点にSSE / SSE2を使用しません。すべてx87です。そのため、あなたが述べたように、モードとフラグについて心配する必要があり、C#では制御できません。したがって、通常の浮動小数点演算を使用しても、プログラムのすべてのマシンでまったく同じ結果が得られるとは限りません。

倍精度の正確な再現性を得るには、ソフトウェアの浮動小数点(または固定小数点)エミュレーションを行う必要があります。これを行うC#ライブラリは知りません。

必要な操作によっては、単精度で問題を回避できる場合があります。ここにアイデアがあります:

  • 関心のあるすべての値を単精度で保存する
  • 操作を実行するには:
    • 入力を倍精度に拡張する
    • 倍精度で演算を行う
    • 結果を単精度に戻す

x87の大きな問題は、精度フラグとレジスタがメモリにスピルされたかどうかによって、計算が53ビットまたは64ビットの精度で行われる可能性があることです。しかし、多くの操作では、高精度で操作を実行し、より低い精度に丸めることで正しい答えが保証されます。これは、すべてのシステムで同じ答えが保証されることを意味します。どちらの場合でも正しい答えを保証するのに十分な精度があるので、余分な精度を取得するかどうかは重要ではありません。

このスキームで動作するはずの演算:加算、減算、乗算、除算、sqrt。sin、expなどは機能しません(結果は通常一致しますが、保証はありません)。 「二重丸めは無害なのはいつですか?」ACMリファレンス(有料登録必須)

お役に立てれば!


2
また、.NET 5、6、または42がx87計算モードを使用しない可能性があることも問題です。それを要求する標準には何もありません。
エリックJ.

5

他の回答ですでに述べたように:はい、これはC#の問題です-純粋なWindowsのままである場合でも同様です。

解決策として:組み込みBigIntegerクラスを使用し、すべての計算を定義された精度にスケーリングすることで、そのような数値の計算/格納に共通の分母を使用することで、問題を完全に回避し、ある程度の労力/パフォーマンスヒットを回避できます。

OPからの要求に応じて-パフォーマンスに関して:

System.Decimal符号用の1ビットと96ビットの整数と「スケール」(小数点がどこにあるかを表す)を持つ数値を表します。すべての計算で、このデータ構造を操作する必要があり、CPUに組み込まれた浮動小数点命令を使用できません。

BigInteger「溶液」は似た何かを-あなたはおそらくあなたが唯一の80ビットまたは精度の240ビットをしたい...あなたが/必要したいどのくらいの数字を定義することができる唯一のこと。

CPU / FPUに組み込まれた命令を使用せずに、整数のみの命令を使用してこれらの数値に対するすべての演算をシミュレートする必要があるため、速度が常に低下します。

パフォーマンスへの影響を軽減するために、QNumbers(Jonathan Dickinsonの回答を参照- 浮動小数点演算はC#で一貫していますか?可能性がありますか?)やキャッシュ(たとえば、トリガー計算など)などのいくつかの戦略があります。


1
BigInteger.Net 4.0でのみ利用可能であることに注意してください。
スビック2011

BigIntegerのパフォーマンスヒットは、Decimalのパフォーマンスヒットでさえも上回ると思います。
CodesInChaos、2011

ここの回答の数回は、Decimal(@ Jonathan Dickinson-'dog slow')またはBigInteger(上記の@CodeInChaosコメント)を使用した場合のパフォーマンスヒットについて言及しています。これらのパフォーマンスヒットについて簡単に説明してください。 /なぜ彼らは本当にソリューションを提供するためのショーストッパーです。
バリー・ケイ

@ヤヒア-編集ありがとう-興味深い読書ですが、「フロート」を使用しない場合のパフォーマンスへの影響については、10%遅くなるか、10倍遅くなるかについて、おおよその予想を教えていただけますか。暗示される程度の感触を得たい。
バリー・ケイ

「わずか10%」よりも1:5の領域でより似ています
Yahia

2

さて、これはこれを行う方法についての私の最初の試みです

  1. 重要な浮動小数点演算に使用する単純なオブジェクトを含むATL.dllプロジェクトを作成します。浮動小数点を実行するためにxx87以外のハードウェアの使用を無効にするフラグでコンパイルしてください。
  2. 浮動小数点演算を呼び出して結果を返す関数を作成します。単純なものから始めて、それがうまくいくなら、いつでも必要に応じて複雑さを増やして、後でパフォーマンスのニーズを満たすことができます。
  3. すべてのマシンで同じように実行されるように、control_fp呼び出しを実際の数学の周りに配置します。
  4. 新しいライブラリを参照してテストし、期待どおりに機能することを確認します。

(32ビットの.dllにコンパイルして、それをx86またはAnyCpuで使用できると思います(または、64ビットシステムのx86のみを対象とする可能性があります。以下のコメントを参照してください)。)

次に、それが機能すると仮定して、Monoを使用したい場合は、他のx86プラットフォームで同様の方法でライブラリを複製できると思います(もちろん、COMではありません。ただし、おそらくワインを使用しますか?私たちはそこに行きます...)。

あなたがそれを機能させることができると仮定すると、パフォーマンスの問題を修正するために一度に複数の操作を実行できるカスタム関数を設定できるはずであり、最小量でプラットフォーム全体で一貫した結果を得ることができる浮動小数点演算が得られますC ++で記述されたコードの残りの部分をC#に残します。


「32ビット.dllにコンパイルしてから... AnyCpuを使用する」これは、32ビットシステムで実行する場合にのみ機能すると思います。64ビットシステムではx86、32ビットDLLをロードできるのは、プログラムをターゲットとするプログラムだけです。
CodesInChaos、2011

2

私はゲーム開発者ではありませんが、計算が難しい問題については多くの経験があります...ですから、最善を尽くします。

私が採用する戦略は基本的にこれです:

  • 遅い(必要に応じて;より速い方法がある場合は素晴らしい!)が、再現可能な結果を​​得るために予測可能な方法を使用する
  • それ以外のもの(たとえば、レンダリング)にはdoubleを使用します。

これのショートとロングは、バランスを見つける必要があるということです。レンダリングに30ミリ秒(〜33 fps)を使用し、衝突検出に1ミリ秒しか使用しない場合(または他の非常に敏感な操作を挿入する場合)-重要な計算にかかる時間を3倍にしても、フレームレートに与える影響は33.3fpsから30.3fpsに低下します。

すべてをプロファイリングし、著しく高価な計算のそれぞれに費やされた時間を考慮して、この問題を解決する1つ以上の方法で測定を繰り返し、影響を確認することをお勧めします。


1

他の回答のリンクをチェックすると、浮動小数点が「正しく」実装されているかどうか、または特定の計算で常に特定の精度が得られるかどうかは保証されませんが、おそらく(1)すべての計算を共通の最小値に切り捨てる(たとえば、異なる実装で32ビットから80ビットの精度が得られ、常にすべての操作が30ビットまたは31ビットに切り捨てられる場合)、(2)起動時にいくつかのテストケースの表がある(加算、減算、乗算、除算、平方根、余弦などの境界線の場合)。実装がテーブルに一致する値を計算する場合は、調整を行う必要はありません。


すべての操作を常に30または31ビットに切り捨てます -これはfloat、x86マシンでデータ型が行うこととまったく同じです。ただし、32ビットのみを使用してすべての計算を行うマシンとは結果がわずかに異なり、これらの小さな変更は時間の経過とともに伝播します。したがって、質問。
BlueRaja-Danny Pflughoeft、2011

「Nビットの精度」とは、計算がその多くのビットに正確であり、マシンAが32ビットに正確であり、マシンBが48ビットに正確である場合、両方のマシンによる計算の最初の32ビットは同一である必要があります。すべての操作の後に32ビット以下に切り捨てて、両方のマシンを正確に同期させませんか?そうでない場合、例は何ですか?
証人保護ID 44583292

-3

あなたの質問は非常に困難で技術的なものですO_o。しかし、私は考えがあるかもしれません。

CPUは、浮動操作の後に何らかの調整を行うことを知っています。そして、CPUは、異なる丸め演算を行ういくつかの異なる命令を提供します。

したがって、式の場合、コンパイラーは結果を導く一連の命令を選択します。ただし、同じ式を計算するつもりでも、他の命令ワークフローでは別の結果が得られる可能性があります。

丸め調整によって行われる「間違い」は、それ以降の指示ごとに大きくなります。

たとえば、アセンブリレベルでは、a * b * cはa * c * bと同等ではないと言えます。

私には完全にはわかりませんが、私よりもCPUアーキテクチャをよく知っている人に尋ねる必要があります:p

ただし、質問に答えるには、CまたはC ++ではコンパイラーによって生成されたマシンコードをある程度制御できるため問題を解決できますが、.NETでは何もできません。したがって、マシンコードが異なる可能性がある限り、正確な結果について確信が持てません。

変動がごくわずかに見えるため、これが問題になる可能性があるのか​​どうか知りたいのですが、本当に正確な操作が必要な場合は、浮動レジスタのサイズを増やすことしか考えられません。可能であれば倍精度またはlong doubleを使用します(CLIを使用してそれが可能かどうかはわかりません)。

私は十分に明確であったことを願っています、私は英語では完璧ではありません(...まったく:s)


9
P2Pシューティングゲームを想像してみてください。あなたは男を撃って、彼を叩いて、彼は死にます、しかし、それは非常に近く、あなたはほとんど逃した もう一方の男のPCでは、わずかに異なる計算が使用され、見逃したことが計算されます。あなたは今問題を見ていますか?この場合、レジスタのサイズを大きくしても効果はありません(少なくとも完全にではありません)。各コンピュータでまったく同じ計算を使用します。
11

5
このシナリオでは、通常、結果が実際の結果にどれほど近いかは(妥当である限り)気にしませんが、重要なのは、すべてのユーザーにとってまったく同じであることです。
CodesInChaos

1
そうですね、私はこの種のシナリオについては考えていませんでした。ただし、これについては@CodeInChaosに同意します。私は重要な決定を2回行うことが本当に賢明であるとは思いませんでした。これは、ソフトウェアアーキテクチャの問題です。1つのプログラム、たとえばシューティングゲームのアプリケーションは、計算を行い、結果を他のプログラムに送信する必要があります。この方法でエラーが発生することはありません。ヒットしたかどうかはわかりますが、決断を下したのは1人だけです。@driushkinと言うように
AxFab

2
@Aesgar:はい、それがほとんどの射手が働く方法です。その「権限」はサーバーと呼ばれ、全体的なアーキテクチャは「クライアント/サーバー」アーキテクチャと呼ばれます。ただし、別の種類のアーキテクチャがあります:ピアツーピアです。P2Pにはサーバーはありません。むしろ、すべてのクライアントは、何かが発生する前にすべてのアクションを相互に検証する必要があります。これにより、ラグが増加し、シューターには受け入れられなくなりますが、ネットワークトラフィックは大幅に減少し、小さなラグ(〜250ms)は受け入れられますが、ゲーム状態全体の同期は受け入れられないゲームに最適です。つまり、C&CやStarcraftなどのRTSゲームはP2Pを使用します。
BlueRaja-ダニープフルフフト

5
p2pゲームでは、信頼できるマシンがありません。1つのステーションが彼の弾丸が当たるかどうかを決定することを許可すると、クライアントが不正行為をする可能性が開かれます。さらに、リンクは時々結果として生じるデータの量を処理することさえできません-ゲームは結果ではなく注文を送ることによって機能します。私はRTSゲームをプレイしていますが、多くのジャンクが飛んでいるのを目にしたことがあるので、通常の家庭用アップリンクで送信することはできません。
Loren Pechtel、2011
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.