web-dev-qa-db-ja.com

最も信頼性が高く効率的なudpパケットサイズ?

UDPで小さなパケットをたくさん送信すると、より多くのリソース(cpu、zlibによる圧縮など)が必要になります。私は here を読んで、UDPで〜65kBYTEの1つの大きなパケットを送信すると失敗する可能性があるため、多くの小さなパケットを送信すると成功する頻度が高くなると考えていますが、処理能力を使用することによる計算オーバーヘッドが発生します(または少なくともそれが私が想定していることです)。問題は基本的にこれです。最大の成功パケットを送信し、計算を最小限に抑えるための最良のシナリオは何ですか?ほとんどの場合に機能する特定のサイズはありますか?サーバーにはErlang、クライアントにはEnet(c ++で記述)を使用しています。 Zlib圧縮も使用しており、すべてのクライアントに同じパケットを送信しています(私が推測する用語はブロードキャストです)。

24
pandoragami

ほとんどの場合、IPフラグメンテーションを引き起こさないUDP payloadの最大サイズは

MTU size of the Host handling the PDU (most of the case it will be 1500) -
size of the IP header (20 bytes) -
size of UDP header (8 bytes)

1500 MTU - 20 IP hdr - 8 UDP hdr  = 1472 bytes

@EJPは534バイトについて話しましたが、私はそれを508に修正します。これは、ホストが設定できる最小MTUサイズが576であり、IP header max size60 bytesになる可能性があるため、FOR SUREが断片化を引き起こさないバイト数です。 (508 = 576 MTU-60 IP-8 UDP)

ちなみに、1472は標準的な十分な値であるため、1500バイトを使用しようとします。

PPPoE接続を通過する場合は、計算に1492ではなく1500を使用します。

26
Davide Berra

UDPで大量の小さなパケットを送信すると、より多くのリソースが必要になりますか?

はい、そうです!ストリーミングアプリで実験をしました。アプリは毎秒2000フレームのデータを正確なタイミングで送信します。各フレームのデータペイロードは24バイトです。 sendto()でUDPを使用して、このデータを別のノードのリスナーアプリに送信しました。

私が見つけたのは面白かった。このレベルのアクティビティにより、送信側のCPUが痛手になりました。 CPU時間の約64%から、約5%になりました!これは私のアプリケーションにとって悲惨なことだったので、修正する必要がありました。バリエーションを試すことにしました。

最初に、sendto()呼び出しをコメント化して、パケットアセンブリのオーバーヘッドがどのように見えるかを確認しました。 CPU時間に約1%のヒット。悪くない。 OK ...sendto()呼び出しでなければなりません!

次に、簡単なフェイクアウトテストを実行しました...sendto()APIを10回の反復ごとに1回だけ呼び出しましたが、以前の10倍の長さで、小さいレコードのコレクションを大きいレコードにアセンブルする効果をシミュレートし、送信頻度を減らします。結果は非常に満足のいくものでした。以前の59%と比較して、7%のCPUヒット。少なくとも私の* NIXのようなシステムでは、パケットを送信する操作は、呼び出しを行うオーバーヘッドだけでコストがかかるようです。

テストが正常に機能していたかどうか疑わしい場合に備えて、実際のUDP送信をWiresharkで観察してすべての結果を検証し、すべてが正常に機能していたことを確認しました。

結論:使用するCPU時間を大幅に減らして大きなパケットを送信する頻度を減らし、同じ量の小さなパケットを頻繁に送信するという形でデータを送信します。確かに、UDPがフラグメント化を開始するとどうなるかわかりません。過度に大きいUDPデータグラム...つまり、これがどれほどのCPUオーバーヘッドを追加するのかわかりません。私は(私自身を知りたい)見つけて、この答えを更新しようとします。

9
JoGusto

534バイト。断片化せずに送信する必要があります。もちろん、それでも完全に失われる可能性があります。失われたパケットの再送信によるオーバーヘッドとネットワークオーバーヘッド自体は、CPUコストよりも数桁大きくなります。

4
user207421