私たちのチームのメンバーは、ゲームエンジンのネットワークコンポーネントの開発について話し合っているときに、UDPを使用して500バイトまたは1kのデータを送信しても、システムのパフォーマンスの観点(データの送信にかかる時間)と変わらないことを示唆しました。
実際には、MTUサイズを超えない限り、送信されるデータのサイズはまったく同じであるため、送信データのサイズは重要ではないと述べました。
それはUDPに当てはまりますか? TCPはどうですか?
それは私には明らかに間違っているように思えますが、私はネットワークの専門家ではありません。
*他の会社のゲームネットワーキングアーキテクチャについて読んでいましたが、それらはすべて送信データを最小限に抑えようとしているため、私の同僚の主張はさらに不合理に見えます。
はい、サイズが重要です。同僚の主張によると、MTUまでのトラフィック量はどれも同じ時間で送信されますが、それは事実ではありません。
少しの間、プロトコルがすべてあることを忘れてください。ビットが一方の端に行き、(うまくいけば)もう一方の端がわかるパイプだけです。パイプが毎秒8,000ビットを転送できる場合、500バイト(4,000ビット)は0.5秒かかり、1,000バイト(8,000ビット)は1秒かかります。これらはすべてシリアルであるため、ほとんどすべての種類のインターフェイスに当てはまります。一部のインターフェイスは、クロックサイクルごとに複数のビットを転送できるという点で部分的に並列ですが、この制限を超えると、それらのユニットのストリームをシリアルに転送します。つまり、基本的な制限が1つあります。
パイプが常に信頼できるとは限らない、またはネットワークを形成するパイプが多数あるために必要なプロトコルを追加する場合は、プロトコルの実装にパケットの処理方法を指示する情報を追加します。その情報は、データに使用できなくなった領域(つまり、転送時間)を占有します(必要なオーバーヘッド)。これなしではプロトコルを実行できないためです。
あなたの例は、ペイロード、UDPプロトコルによって追加された8バイトのヘッダー、およびIPプロトコルによって追加された20バイトのヘッダーを含むUDP/IP *パケットです。 500バイトのデータグラムを送信する場合、プロトコルによって課される28バイトのオーバーヘッドは、送信する必要がある528バイトのパケットの5.3%を占めます。ペイロードを1,000バイトに増やすと、オーバーヘッドレート2.7%で、1,028バイトのデータグラムごとに独自のデータをより多く送信します。 MTUが大きく、10,028バイトのパケットを飲み込む可能性のある伝送媒体がある場合、オーバーヘッドはさらに0.3%まで減少します。
TCPはUDPよりも複雑なプロトコルであり、20バイトのヘッダーがあるため、IP経由で実行した場合、合計オーバーヘッドは40バイトになります。 500バイトと1,000バイトのペイロードの例では、オーバーヘッド率は7.4%と3.8%になります。
これらのTCP/IPまたはUDP/IPパケットをイーサネット経由で送信すると、イーサネット自体のヘッダーが14バイト、トレーラーが4バイト、フレーム間のアイドル時間が12バイト追加され、合計で30バイトになります。上記のプロトコルと同様に、ペイロードが大きいほどフレームが少なくなり、フレームが少ないほどオーバーヘッドに費やされる時間が短くなります。
オーバーヘッドを抑えるために任意の大きさのパケットを送信しない理由はいくつかあります。それらの最大の理由は、途中で6バイトを失ったために、メガバイトのデータ全体を再送信する必要がないことです。伝送媒体が非常に信頼できることを知らない限り、オーバーヘッドを被る方がはるかに良いので、1キロバイトのフレームを再送信するだけで済みます。
これと並行する現実の世界では、輸送に53フィートのトラックを使用します。ドライバーを雇って多くのドライバーがそれぞれ2つだけのものを運ぶためにドライバーを雇ってガソリンを購入するよりも、それぞれをできるだけしっかりと梱包する方がはるかに安価です。
*通称[〜#〜] udp [〜#〜]は実際にはDP over IPまたはDP/IPです。 UDPは実際にはIP以外のプロトコルの上で実行することもできますが、IPが圧倒的に一般的なケースです。
Dbasnettのコメントに対処するには:重要なのは、UDP isが他のプロトコルの上で実行されるということではなく、プロトコルレイヤーケーキ内のその場所がすることができるであることを意味します。トランスポート層プロトコルであるUDPは、ホストアドレッシングがネットワーク層によってすでに処理されていることを前提としています。つまり、必要なのが送信ポートと受信ポートを識別することだけであれば、ほとんど何でもUDP(およびUDP/IPではなくUDP)を実行できます。 2つのホスト間のシリアルリンク(アドレス指定は暗黙的であるため、ネットワーク層がない)が機能します。イーサネットフレームも、MACアドレスがホストを特定するのに十分である場合にそうなります。誰かが実際にこれを行うと言っているわけではありませんが、適切に設計されたネットワークスタックを使用すると、上位層が気にせずに下位層を置き換えることができます。
それはすべて、「送信時間」と見なすものに依存します。 send()
とrecv()
の呼び出し間の経過時間を考慮すると、これはいくつかの要因に依存し、パケットサイズは計算にあまり関係しない場合があります。その場合、一部のケース(ただし、私は繰り返しますが、すべてではありません!)で、TCP、UDP、大きなパケットまたは小さなパケットなど、ほとんど何も変更しないと言うことができます。
それ以外の場合、実際には有益いくつかのシナリオでは合計送信時間を短縮するために小さいパケットが必要です。例:エラーの可能性が高い場合、and再送信する必要がありますand非常に大きなパケットを使用すると、すぐにエラーの再送信時間が計算を支配し始めます。パケットサイズを大きくすると、コストとエラーの確率が増加し、送信時間が長くなります。 singleパケットの極端なケースでは、その1つのパケットが損傷する確率は1に近づき、1,000回の再送信が必要になる場合があります。時間の増加は100000%になりました。パケットが1000分の1になると、そのうちの10パケットが損傷し、それらのみを再送信します。全体の時間はわずか1パーセント増加します(再送信プロトコルによって異なります)。
オーバーヘッドも考慮する必要があります。送信するBペイロードバイトのすべてのパケットには、Oバイトのオーバーヘッドがあります。単純化して、パケットの物理送信時間がそのサイズの線形関数であると仮定すると(そうではない)、Nバイトを送信するには、N/Bフレームを送信する必要があります。つまり、(N/B)*(B + O)= N(1 + O/B)バイト、およびkN(1 + O/B)伝送時間。ご覧のように、Bが小さいほど時間が長くなります。サイズがゼロの架空のパケットは、ペイロードデータの送信がまったくないことを意味します。したがって、上記のシナリオの正反対の無限の時間になります。
最も抽象的なレベルでのみ-オーバーヘッドと一定時間の送信はありません-はい、送信時間はk(N/B)* Bです。これはkNであり、Bに依存しません。そして、再び、最初の「事故」モデルの遭遇は、おそらくMTUサイズに到達する際の不連続です。
ただし、一般的にはnotは実際に起こっていることを忠実に表しています(オーバーヘッドを考えてください。エラーを考えてください。下位層のオーバーヘッドを考えてくださいs、複数...そして、これはおそらくseveral Hops)のルート上にあり、パケットサイズは重要かもしれませんa lot。
多くの場合、単純なヒューリスティック(「小さいほど良い」、「大きい良い」など)のため、実際の最良の値を見つけるために実験を行う必要があります。 )は、最良の結果をもたらすことはありません。
XPラップトップを使用しているので、_netstat -snap tcp
_を使用すると、エラー率で動作するデータが得られます。パケットサイズの統計情報がないので、もちろん、そうでない場合でも、それらはすべて約1500バイトです。
私の統計は実際のエラー率を示し、バイトがデッドの場合はパケットがデッドであると想定しているため、バイトレベルのエラー確率Pbは、「パケットが成功するためには、すべてのバイトそのまま通過する必要があります」、すなわち、
_1 - Pp = (1 - Pb)^PacketSize
_
これにより、Pbを1-exp(ln(1 - Pp)/PacketSize)
として導出できます。その時点で、他のPacketSizeのパケットエラー確率を再計算し、そこから同じペイロードを送信するのにかかる時間を決定できます。
理論的にはrightであると主張できますが、それはサイズが重要であることが判明したためです。しかし、それはごまかしです-私は実際に間違っていました、少なくともこのシナリオでは、-サイズは非常に重要ではありません:
したがって、パケットサイズは依然としてアプリケーションの設計に影響を与える可能性がありますが、データ送信時間のためではありません。
他の回答はすでにデータサイズの部分についてコメントしていますが、違いを測定するために関連する別の要因があります
TCPはデータパッケージを送信するだけでなく、それらを送信する前に追加のパッケージを送信して接続を作成し、パッケージの取得を確認して、最後に追加のパッケージを送信して接続を閉じます。
これの利点は、すべてのデータが完全かつ正しい順序で受信されたことが保証されることです。アプリケーションでこれらの保証を構築することは、システムで実績のあるTCP実装を使用するよりも複雑になることがよくあります。Googleが現在取り組んでいるにもかかわらず [〜#〜] quic [〜#〜 ] 、UDPに基づいてWebコンテンツを送信するプロトコルです。任意のパッケージが失われても問題がない場合にのみ、何らかの形式の保証とUDPが必要な場合は、TCPを使用することをお勧めします。
BlrflとLSerniの回答は、すでにさまざまなパケットサイズのオーバーヘッド(サイズ、次に時間)に対処しています。また、エラーに関するトレードオフについてもすでに対処しています。
その上に ...
オンラインゲームは非常にインタラクティブであり、アプリケーションがより小さなチャンクで(完全なパケットを待たずに)何かを実行できる場合(そしてその場合に限り)、わずかな遅延でも目立ちます。送信するようにプロトコルを設計する方がよいでしょう。 複数の小さな自己完結型パケット(および必要なオーバーヘッドを受け入れるため)、それが他社のゲームネットワークがパケットサイズを最小化しようとする理由です:ラグが短い場合、認識される速度はより高速です。
1つの例で説明します。4つの文字のテクスチャを送信する必要があります。2つのケースがあります。
想像できるように、2番目のケースの合計時間は比較的短いですが、知覚されるゲーム速度ははるかに悪いです。
要するに、あなたの同僚は間違っています(そしてTCP/UDPの上にある各レイアウトはますますオーバーヘッドを追加することを忘れないでください)が、オンラインゲームのパフォーマンスを改善することは生のネットワーク速度ではありません。
各プロトコルにカスタムプロトコル/ヘッダーがある場合->パケットを小さくすると、ヘッダーは%大きくなります。
Headersizeが100バイトであるとしましょう。そして、あなたのパケットサイズオプションが200または400のいずれかであるとしましょう! 200を選択すると、ヘッダーは50%になり、400を選択すると、ヘッダーは25%になります。
そして、各パケットを数百回/数千回送信すると、問題は拡大します!
10 mb /秒を送信すると、その50%はパケットサイズ200のヘッダーデータになります。
したがって、パケットサイズを最大化して、ヘッダーサイズが限界になり、メタデータよりも多くのデータを送信できるようにすることをお勧めします。本当に、そのすべては効率的であることについてです。その常識!
編集:それに関係なく、「UDP」自体はプロトコルです。つまり、メタデータは関係なく交換されます。したがって、実際には、ヘッダーがあるかどうかに関係なく、常にメタデータが存在します。オーバーヘッドを回避するには、パッケージサイズを最大化してください。