UDPは、通常、データ使用量の多いリアルタイムマルチプレイヤーゲームに推奨されることを知っています。
ほとんどの記事は数年前に作成されたものであり、インターネット上で送信されるすべてのデータの〜80%がTCPであるため、TCPに対して多くの最適化が行われたに違いありません。
これは私に不思議にさせます:UDPはまだ速度と待ち時間の点で優れていますか?最近のTCP最適化により、TCPはUDPよりもパフォーマンスが向上しましたか?
UDPは、通常、データ使用量の多いリアルタイムマルチプレイヤーゲームに推奨されることを知っています。
ほとんどの記事は数年前に作成されたものであり、インターネット上で送信されるすべてのデータの〜80%がTCPであるため、TCPに対して多くの最適化が行われたに違いありません。
これは私に不思議にさせます:UDPはまだ速度と待ち時間の点で優れていますか?最近のTCP最適化により、TCPはUDPよりもパフォーマンスが向上しましたか?
回答:
いいえ、UDPはパフォーマンスレイテンシの点で依然として優れており、2つのプロトコルの哲学により、常に高速になります-通信データがUDPまたはその他の損失の多い通信を念頭に置いて設計されていると仮定します。
TCPは、すべてのネットワークパケットが到着する抽象化を作成し、送信された正確な順序で到着します。損失の多いチャネルでこのような抽象化を実装するには、時間を消費する再送信とタイムアウトを実装する必要があります。TCPで2つの更新を送信し、最初の更新のパケットが失われた場合、次の更新まで2番目の更新は表示されません。
UDPを使用すると、最初の更新を破棄し、2番目の新しい更新をすぐに使用するため、TCPでこれがどれほど速く行われても問題ありません。TCPとは異なり、UDPはすべてのパケットが到着することを保証せず、パケットが順番に到着することを保証しません。
これには、適切な種類のデータを送信し、データの損失が許容されるように通信を設計する必要があります。
すべてのパケットが到着する必要があるデータがあり、パケットが送信された順序でゲームによって処理されなければならない場合、UDPはより速くなりません。実際、この場合にUDPを使用すると、TCPを再構築し、UDPを使用して実装するため、TCPを使用する可能性があるため、おそらく遅くなります。
編集-いくつかのコメントを組み込む/対処するための追加情報を追加します。
通常、イーサネットでのパケット損失率は非常に低くなりますが、WiFiが関与するか、ユーザーがアップロード/ダウンロードを実行している場合、パケット損失率ははるかに高くなります。0.01%の完全に均一なパケット損失があると仮定しましょう(往復ではなく一方向)。一人称シューティングゲームでは、マウスカーソルがプレーヤーを回転させるなど、何かが起こるたびにクライアントが更新を送信する必要があります。また、フレームごとまたは一定の間隔で更新を送信できます。これは、1秒あたり60〜120の更新です。これらの更新は異なる時間に送信されるため、更新ごとに1パケットで送信されます。16プレーヤーのゲームでは、16プレーヤーすべてがこれらの1秒あたり20〜120パケットをサーバーに送信し、結果として合計で1秒あたり320〜1920パケットになります。パケット損失率が0.01%の場合、5.2-31.25秒ごとにパケットが失われると予想されます。
失われたパケットの後に受信するすべてのパケットで、DupAckを送信し、3回目のDupAckの後、送信者は失われたパケットを再送信します。したがって、TCPが再送信を開始するのに必要な時間は3パケットに加えて、最後のDupAckが送信者に到着するのにかかる時間です。次に、再送信が到着するのを待つ必要があるため、合計で3パケット+ 1ラウンドトリップレイテンシを待ちます。ラウンドトリップ遅延は通常、ローカルネットワークでは0〜1ミリ秒、インターネットでは50〜200ミリ秒です。通常、1秒あたり120パケットを送信する場合、25ミリ秒で到着し、1秒あたり20パケットを送信する場合、150ミリ秒で3パケットが到着します。
対照的に、UDPでは、次のパケットを取得するとすぐに失われたパケットから回復するため、1秒あたり120パケットを送信すると8.3ミリ秒、1秒あたり20パケットを送信すると50ミリ秒を失います。
TCP では、Nagle(開発者が送信合体をオフにするのを忘れた場合、または遅延ACKを無効にできない場合)、ネットワーク輻輳回避、またはパケット損失が十分でないために複数を考慮する必要がある場合、さらに厄介になりますパケット損失(AckおよびDupAckの損失を含む)。UDPを使用すると、TCPのような優れたネットワーク市民であることにまったく関心がないため、より高速なコードを簡単に記述できます。
TCPとUDPの両方がIP上に構築されたプロトコルであることに同意します。IPは、インターネットを介したメッセージの配信方法を指定しますが、メッセージの構造、形式については何もありません。TCPおよびUDPプロトコルが登場しました。IPプロパティを使用しますが、プログラマはネット通信の下位層を心配することなくメッセージ交換に集中できます。そして、それは素晴らしいことです。なぜなら、ワイヤー内のアナログ信号を直接処理するのは、ちょっと痛いからです。
TCPは、メッセージを送受信するための一連の機能を提供します。データを小さなパケットに分割し、ネットワーク経由で送信します。求められるのは、ネットソケットに使用するポートと、送信する実際のメッセージだけです。また、信頼性が高いため、ネットワーク上でパケットが検出された場合、パケットが検出された後、到着するはずの順序で送信するように注意して再送信されます。
一方、UDPはユーザー制御を指向したプロトコルです。UDPを使用してデータグラムを送信する場合、データグラムが宛先に到着するかどうかはわかりません(ここで数学的な確実性を意味します:パケットを送信すると、おそらく到着しますが、 100%)。また、パケットが失われた場合、検出も送信もされません。
この時点で、TCPはすべての問題に対する理想的なソリューションのように見えます。信頼性が高く、高速で、到着したパケットと送信する必要があるパケットを追跡することで、接続の遅延を解決します。
しかし、超えて見てください。UDPが提供する唯一の利点はその速度であり、それこそまさに私たちが本当に望むものです。UDPパケットは、UDPプロトコルが機能する方法であるため、特定の制御なしで作成され、チェックされ、送信されるだけです。TCPパケットを作成、ラベル付け、sumcheckedし、到着するとACKを送り返して送信者に「パケットxはここにあります」と伝え、この信号が送信されない場合はそのようなパケットxを送信する必要があることを意味します再び。
UDPは、通常、データ使用量の多いリアルタイムマルチプレイヤーゲームに推奨されることを知っています。
はい、しかしそれだけではありません。UDPは主にTCPよりも優先されます。これは主に、データの送信と管理を高速に処理するためにUDPが高速であるためです。これは、そのようなビデオゲームが決定的なロックステップで実行されると仮定すると発生します(サーバーで発生することは、ネットワーク遅延とは無関係にどのクライアントでも同じように複製されます)。更新パケットが失われ、宛先に到達しません。TCPはそのようなパケットを再送信し、次のパケットは順番どおりに到着しないためにドロップされ、その後、失われたパケットの後に再送信されます。このシナリオでは、UDPの方がはるかに寛容です。新しいパケットが来るので、このパケットは気にしません。失われた更新はレンダリングされず、代わりに、使用される統合方法と受信された最新の更新に基づいてゲームの物理が補間されます。
遅延が十分に大きい場合、TCPはジッターを引き起こしますが、UDPはそうではありません。
<video style="min-width: 100% height: auto" autoplay="" preload="auto" loop="true"><source src="https://gafferongames.com/videos/deterministic_lockstep_tcp_250ms_5pc.mp4" type="video/mp4"><source src="http://173.255.195.190/cubes_deterministic_lockstep_tcp_250ms_5pc.webm" type="video/webm">Your browser does not support the video tag.</video>
これは、UDPがまだ速度と遅延の点で優れているのではないかと思います。
まあ、はい、それはそうであり、それは長い間続きます。TCPとUDPの詳細については、こちらをご覧ください。
TCP <-伝送制御プロトコル。伝送を制御するために作られました。
TCPは、優れた外交ネットワーク市民になるために作成されました。ネットワーキングを誰にとっても良い体験にすることに焦点を当てており、それを達成するためのスループットを喜んで低下させます。遅延を追加することで環境に適応します。理由は次のとおりです。
さらに
これらにも関わらず、TCPは(送信データ全体)/(消費時間全体)の最高値を提供します。ちょうどあなたがそれが起こることを望むとき、それは正確に起こりません。
UDPはこれらのいずれも行いません。それはあなたの意志に応じて発動し、毎回命中することは期待できないというだけです-標的を封じ込めると、「長い間撃っていないのに、なぜですか」と告げなければなりません。独自のカスタムACKパケットを作成したり、単一のパケットに複数のレコードを配置したりすることもできます。また、重要なことは、NATトラバーサルを制御することです。UDPは、待ち時間の少ないゲームに最適です。
あなたは最初の図と比較してもよいRFC 768(UDP)の最初の図をRFCP 793(TCP)15ページ。
両方とも、「送信元ポート」に16ビットが続き、「宛先ポート」に16ビットが続きます。どちらも「チェックサム」に対して16ビットを示します。RFC 768によれば、UDPの「チェックサム手順はTCPで使用されるものと同じです。」
UDPの長さはUDPの図の詳細をまとめますが、TCPの長さは15ページと16ページで説明する「96ビットの擬似ヘッダー」の一部です。
TCPがUDPを上回るとは思わないでください。複数の理由から、それは起こりそうにないだけです。1つは、TCPが単により多くのビットを持っているということです。したがって、機器が1秒あたり特定のビット数を効果的に処理できる場合、TCPパケットよりも多くのUDPパケットが許可されます。
もう1つの理由は、TCPの「スリーウェイハンドシェイク」は、送信者が応答を待たなければならないことを意味することです。この要件により、UDPで処理できないオーバーヘッドが追加されます。ほとんどのインターネット通信がUDP通信で始まる理由があります。基本DNSはUDPを使用します。これは、TCPの「3方向ハンドシェイク」プロセスよりも少ないステップで要求と応答を完了することができるためです。失われたパケットを追跡するTCPの機能は、エキサイティングではありません。なぜなら、コンピュータは、未完了の前の要求があることをリモートシステムに知らせるのではなく、単に新しい要求を行うことができるからです。
しばらくの間何が起こっているかを考えてください。シナリオを単純化するために、状態の変更を送信するときに2つの選択肢があります(プレイヤーが方向を変えた、銃を撃った、または他のプレイヤーが爆弾を発射したなど)。
その直前に更新が必要なかったと仮定すると、その単一の更新が1対2で到着する時間は大きく異なりません。サーバーからクライアントへの1回の旅行です。しかし、ただ爆弾が飛ぶのではなく、迷路を走っている人の活動を継続的に伝えようとしていると言います。織り、ダッキング、射撃など。UDPの場合、すべてのアクションは、発生するとすぐにデータグラムで送信されます。TCPの場合、サーバーが送信を許可されている場合にのみ、すべてのアクションがパケットで送信されます。送信が許可されているとはどういうことですか?TCPウィンドウに余裕を持たせる(遅延ackがアクティブであると想定)ため、メッセージをワイヤ上に置くことができます。そうでない場合は、送信する前にクライアントからackが到着するのを待つ必要があります。
長すぎますか?マルチプレイヤーのファーストパーソンシューティングゲームの開発がヒットしたとき、90年代後半から2000年代初頭の低遅延接続は一般的ではありませんでした。ダイヤルアップモデムの一般的な一方向の遅延は180ミリ秒です。別の更新を送信する前にackを待ち、その時間を事実上360ミリ秒に倍増するのは苦痛でした。初心者ユーザーでも間違いなく違いを感じることができました。ブロードバンド接続が普及すると、遅延は大幅に減少しましたが、帯域幅が不足している場合でも持続しました(一部の地域ではかなり頻繁に)。そのため、可能な限り最小の待機時間の設定が維持されました。
現代のホーム接続と相互接続はこれを変更し、1日の混雑した時間帯であっても地域の遅延が15ミリ秒以下の範囲に収まるようになりました。レイテンシが「十分に低い」ため、UDPの代わりにTCPを選択することはほとんどの場合目に見えません。ただし、低遅延プロトコルとしての歴史を考えると、UDPはTCPよりも優先される傾向がまだあります。そのため、現時点(およびおそらく将来)で、UDPがリアルタイム通信に優先されます。
UDPは、通常、データ使用量の多いリアルタイムマルチプレイヤーゲームに推奨されることを知っています。UDPは
、速度と遅延の点でまだ優れていますか?最近のTCP最適化により、TCPのパフォーマンスはUDPよりも優れているでしょうか?
あなたの仮定は間違っています。TCPとUDPの主な違いは、それらが表すモデル(信頼性の低いデータグラムと順序どおりの信頼性のある仮想ストリーム)です。
ボリューム(「高いデータ使用量」)またはスループットに関して違いはありません。TCPはUDPと同じだけのデータをプッシュし、物理ケーブルを簡単に飽和させます。
パケット損失が存在する場合、この2つの遅延は実際には異なりますが、その条件のみが異なります。それ以外の場合、TCPの遅延はUDPと同じくらい低くなります(ネットワークスタックにはやや多くのロジックがあるため、数十ナノ秒かかる可能性がありますが、それは無視できます)。
ヘッダーのサイズにはわずかな違いがあるため、技術的には、より多くのバイトをシリアル回線上の回線で送信する必要がありますが、これもかなり重要ではありません。バルク転送の場合にのみ重要であり、その後は約0.5%の差があります。ホームDSLインターネットアクセスを持つほとんどの人は、すべてのトラフィックをATMでルーティングします。これにより、10%のプロトコルオーバーヘッド(48バイトのペイロードに対して5制御バイト、および部分フレーム)が追加されます。
一部の人々は、UDPの上に信頼性を構築します。ある程度の信頼性が必要であるが、厳密な順序通りの配達が必要でない場合、それは小さな利点を与えるかもしれません。しかし、このアプローチが理にかなっているかどうかはまだ議論の余地があり、その小さな利点に対して多額の費用を払っています。
ホテルのWiFiやその他の「奇妙な」場所から接続しているクライアントがある場合、TCPの全体的なサポートがUDPよりもはるかに優れていることがよくあります。
ゲームは一般にUDPを使用します。前述の方法のいずれかで優れているからではありません-または、順序なしで信頼性を実装することでジッタを0.5ミリ秒減らすことができますが、ゲーム(IPテレフォニーのような)多くの場合、位置の更新など、非常に揮発性の高いデータが多く含まれています。
この揮発性データは、時間の経過と次のデータグラムの両方によって定期的かつ迅速に廃止されます。これは、100%の信頼性(または順序どおり)を気にしないということを意味します。
頻繁に更新されるゲーム(シューティングゲーム、電話、ビデオチャット)で安定したペースで実行されるサービスでネットワークパケットがドロップされると仮定すると、確認応答がタイムアウトしてパケットを再送信することはあまり意味がありません。再送パケットの到着を待っている間、もう一方の端ですべてを凍結します。それはあまりにも邪魔であり、良くありません。
代わりに、パケットの損失を考慮して先に進み、それを通過する次のパケットからデータを取得し、その間、可能な限り、パケットがユーザーから失われたという事実を隠します。補間、推測航法、あなたはそれに名前を付けます。
パケット損失は正常な状態であることに注意してください。IPは一般に「非常に信頼性が高い」のですが、ときどきドロップされるパケットは発生する可能性があり、発生します。パケットが失われるのは通常、まれにありますが(ここでは1%未満)、異常または理論的なものではなく、何かが壊れていることを示すものでもありません。それは完全に正常です。たとえば、
すべてのTCPバルク転送には、必然的に失われたパケットが含まれます(輻輳制御の仕組みです)。
高帯域幅MPGでは、モンスター#425の位置とヘルスを提供するパケットを見逃しても気にしません。1秒以内に別の更新を取得するからです。これは、UDPによりTCPが馬鹿げたように見えて、即座に陳腐化したデータを待機させる例です。
同じゲームで、パッチが設計どおりに表示されるようにします。TCPには既に「失敗した場合は教えてください」機能が組み込まれており、自動再試行と検証された失敗が容易になります。UDPで実行できますが、なぜテクノロジーを再作成するのですか?
これから何が起こっているかを簡単に説明します。
UDP-チャンクO'dataを分離します。
パケットを作成します。
IPでカプセル化します。
それを出荷。
TCP-ストリームO'dataを分離します。
ストリームの先頭からパケットを作成します。
IPでカプセル化します。
TCPウィンドウのスペースを待ちます。
それを出荷。
領収書を受け取るか、タイムアウトするまで、再配送を続けます。
レシートが受信されるかタイムアウトになるまで、TCPウィンドウにとどまります。
出荷とは、ローカルNICを介して到達したことを意味します。
TCPレシート受信は、データ受信を保証し、次のパケットのためにウィンドウ内のスペースを解放します。
(わずかに)再送すると、最終的に受信される可能性が高くなります。
TCPパケットは、データの順序付けられたストリームとして反対側で再構成されます。UPDパケットは個別のパケットとして受信されます。プロトコルは順序を保持しません。
TCPは、必要なデータと大量のデータをプッシュするのに適しています。TCPは永続的な障害の通知を提供します。TCPは、チョークされたパイプを介して自己調整します(ref:window)。TCPには初期化を遅くするためのハンドシェイクがあります。TCPでは、送信の前に「接続」が必要です。
UDPは単にデータを送信するだけで、ウィンドウや再送信を待たずに続行できます。UDPは、失われたデータの量に関係なく、データを全速力でチョークパイプに送ります。
商用に適用されたUDPマルチキャストファイル転送ユーティリティを設計および作成しました。私はIPスタックに取り組んできました。これらは単なる基本であり、細かい点はありません。「ソケット、MTU、およびその他の楽しいおもちゃ」の説明は、この質問に役立つものを少し超えていました。
Ps(コメントに返信するコメントを追加することはできません)UDPは、望ましいが必須ではないデータにも適しています。Forward Error Correctionは、この例であり、多くの不必要ではあるが望ましいパケットです。
すべてのTCP最適化ルーターは、TCPをUDPよりも優れたパフォーマンスにしましたか?
もう1つの質問は、「データが重い」ということは、シーンを頻繁にロードするということですか?
はいの場合、特にサーバー側ではNICが同じサイクルのさまざまなオフロードを提供するため、TCPがより効率的になる可能性がある大量のデータ(> 1k)を集中的に送信する必要があります。ユーザー空間アプリケーションはTCPで大量の書き込みを発行する場合がありますが、UDPではMTUヘッダーサイズバイトを超える送信を試みるとIPフラグメンテーションやパフォーマンスを低下させるその他のオーバーヘッドが発生します
UDPまたはTCP(またはその他のバリアント)は、速度/レイテンシの面でも、まったく優れたものではありません。アプリケーションの要件に応じて選択する必要があります。これを行うには、各プロトコルが提供する機能を比較し、機能が増えるとオーバーヘッドが増えることを理解する必要があります。そのため、目標がレイテンシを最小化するか速度を最大化することである場合、要件を満たすために必要な重要な機能を維持しながら、できるだけ機能の少ないプロトコルを選択する必要があります。
一般的に、UDP(ユーザーデータグラムプロトコル)は最小限の機能を提供します。受け取り/確認の種類なしでデータを送信するという点で単純です。
一方、TCP(Transmission Control Protocol)は、信頼できる接続された通信に必要な多くの機能を提供します。TCP通信は、重複するパケットまたは複数のパケットを送信し、順序付け情報でタグ付けします。宛先で受信すると、元の送信者が失われたパケットを再送信できるように、ACK(確認応答)が失われたパケットに関する情報とともに返送される必要があります。正しくリコールすると、ACKパケットでさえ適切な信頼性のために確認が必要になる場合があります。
Skypeの電話会議では、すべてのビデオおよびオーディオデータが信頼性の高い方法で送受信されるようにすることは重要ではありません。最近では、UDPはとにかくパケット損失を最小限に抑える上で素晴らしい仕事をしています。知っておくべき重要なことは、送信が成功したかどうかにかかわらず、UDPにはまったく保証がないということです。電話会議のオーディオ/ビデオデータの場合、リアルタイムデータ(つまり、最新のデータ)の取得を重視するため、UDPが適切な選択です。あちこちでいくつかのパケットが失われても、劇的な方法で通信を中断することはありません。
ただし、電話会議では、人々はIM(インスタントメッセージ)またはファイルを送信できます。これらの場合、信頼性は、ファイルとメッセージが破損または失われないことを保証するために必要な要件です。IMの場合、TCPが提供する接続状態は必要ない場合があります。RUDP(Reliable UDP)などの中間プロトコルで十分な場合があります。ただし、ファイルの場合は、TCPが提供する接続状態にする必要がある場合があります。
複雑なアプリケーションがある場合、または通信を最適化する必要がある場合は、UDP通信から始めるのが有益です。その後、必要な機能をすべて上に追加できます。これにより、ネットワーク通信を最大限に制御できます。
最適化が不要な単純なアプリケーションがある場合は、ニーズを満たすためにいずれかの標準(UDPまたはTCP)を使用することを検討してください。それはあなたがより重要な問題に進むことを可能にするでしょう。
TCPパケットはUDPパケットよりも大きいと人々が考える多くのコメントに気付きました。ただ私を信じるのではなく、ドキュメントを読んでください。プロトコルは次のとおりです。イーサネットヘッダーの場合は数バイト(2バイトのメッセージタイプ、48ビットMAC、6バイト)(Wifiの場合、ヘッダーは異なる場合があります)IPの場合は20バイトTCPの場合は20バイトxデータの場合はxバイト0から約1500(MTUを参照)最後に、そのイーサネットパケットで破損が発生していないことを確認するチェックサム。
TCPでは、約64Kのより大きな「ストリーム」パケットを送信できます。この「大きな」ブロックは、実際には多くの小さなイーサネットパケットに刻まれています。