Ubuntu 22.04がインストールされている2台のコンピュータ間に追加の高帯域幅トラフィックがあると、待ち時間とジッタが減るのはなぜですか?

Ubuntu 22.04がインストールされている2台のコンピュータ間に追加の高帯域幅トラフィックがあると、待ち時間とジッタが減るのはなぜですか?

イーサネットケーブルを介して2台のコンピュータが接続され、Ubuntu 22.04がインストールされています。コンピュータB)のサーバーにUDPパケットを送信するコンピュータA)にクライアントがあり、さまざまなシナリオでこれらのパケットの待ち時間とジッタを測定しています。私はソケットライブラリを使ってCでクライアントとサーバーのソースコードを書いた。

待ち時間を測定するパケットに加えて、2つのシステム間に追加の高帯域幅トラフィックがある場合、追加のトラフィックなしでパケットを送信するよりもジッタと待ち時間が短くなります。

  • 追加トラフィックのない往復時間:0.556ms
  • 追加トラフィックの往復時間:0.105ms
  • 追加トラフィックのないジッタ:0.042ms
  • 追加トラフィックのジッタ:0.014ms

パケット数が少ないと待ち時間とジッタが減ると思っていたので、これは面白かったが、結果はそうではなかった。なぜ何なのか教えてくれる人はいますか?これは、より多くのパケットが到着したときにバッファをより頻繁に空にする必要があるバッファの最適化に関連していると思いますが、わかりません。この場合、待ち時間を最小限に抑えるようにバッファをどのように設定できますか?

編集#1:提案されているように、NIC構成(ethtool -c)のパラメータを変更してみました。 ethtoolの設定

rx-usecs 3 の初期値を rx-usecs 1 us にのみ変更できます。 Adaptive-rx および rx-usecs-low は変更できません。私のネットワークカードはそれをサポートしていないようです。

rx-usecs の値を 1 に減らしても問題は解決しません。 2 つのシナリオ間の待ち時間の差は、増加しない限り同じままです。

5と10に増やすのも役に立たないようです。

答え1

ネットワーク遅延とジッタを減らすには、トラフィックに関係なく常にCPU負荷を増やし、場合によってはトラフィックの多い状況でスループットを下げることもあります。

A / Ultimate Hammer:忙しく投票してください!(重要な警告は、CPUが少ないほど他の領域でより多くの犠牲が続くことです。)

アイデアは、いくつかのブロックを実行して忘れてrecvmsg他のタスクのためにCPUを解放するのではなく、最終的にCPUキャッシュをフラッシュし、いくつかのコンテキスト切り替えとSoftirq処理の後に最終的にタスクに戻ることです....ループネットワークカードから何かが出るのを待つゆっくり忙しいです。
バッファでデータが利用可能になると、追加の遅延なしに処理されます。

man recvmsgこれに関連する部分を参考にしてお読みください。MSG_待たないでくださいバナー。また、ソケットを開けても同様の効果が得られます。O_非遮断また、ポーリングはコアを介して実装することもできますが、個人的にはこのアイデアは気に入らません。なぜなら…コアが2つしかないからです… ;-)

つまり、タスクを1つのCPUに固定したいと思います。これにより、ジョブの移行のオーバーヘッドが防止され、キャッシュをホットに保つのに役立ちます。

このアプローチの利点は即時です!スループットに影響を与えずに待ち時間とジッタを最小限に抑えますが、無料のランチのようなものはないので、可能な限り高いCPU負荷です。

B/低レベルのネットワークカード調整(割り込みマージ、リングバッファ、転送キュー... from ethtool

- バッファ:通常、どのサブシステム(ネットワーク/サウンド/…)バッファもレイテンシ/ジッタの敵です。したがって、これを最小限に抑える必要があります。
厳しい最小値は何ですか?
負荷が高いと、パケット損失および/またはオーバーフローが開始されます(報告されているようにifconfig)。

- 割り込みマージ: 割り込み統合は、パケットがホストメモリにあるためパケット到着時間の遅延を増加させるが、ホストは一定時間が経過するまでパケットを認識しない。ただし、割り込みの数が少なくなり、ホストが割り込みごとに複数のパケットを処理するため、システムはより少ないCPUサイクルを使用します。
したがって、CPU時間とスループットを犠牲にして、マージをできるだけ低い程度に減らすことが興味深いことがわかります。

  • もちろん、次のような場合には必要ありません。忙しいポーリング
  • もちろん、関連するIRQが利用可能なすべてのコアに均等に分散していることを最初に確認しないと、マルチキューネットワークカードにほとんど影響しません。
  • もちろん、システムが稼働していなければ何の効果もありません。割り込みスレッドIRQ処理の実際の作業は、リアルタイムスケジューリングポリシーに従う専用のカーネルスレッドによって実行されないためです。

答え2

ネットワークドライバとスタックは、イーサネットフレームを受信したり送信フレームを完了したときにカードが割り込みを発生させるモードで本質的にカーネルが必要なものかどうかを尋ねるため、できるだけ早くカードを調べるモードに自動的に切り替えることができます。処理されます。

新しいパケットが到着するたびに直感的に割り込みを受け取ることは待ち時間を減らすように聞こえますが、割り込みを処理するには少し準備が必要なので時間がかかるという考えです。高速通信が進むと、パケットが処理され、すべてのカーネル管理が完了した後に処理を待つ新しいパケットがほぼ確実に存在します。したがって、中断はワークフローを中断し、実際に使用できる時間を短縮します。扱う(単にパケットの存在に反応する代わりに)

ethtool -Cethtoolのマニュアルページを調べて、どのオプションが理解されているかを確認して動作を制御できます。sudo ethtool -c ${YOUR_ETHERNET_INTERFACE_NAME}以下を使用して現在のオプションを確認する必要があります。

Coalesce parameters for ${YOUR_ETHERNET_INTERFACE_NAME}:
Adaptive RX: on  TX: off
stats-block-usecs: 50
sample-interval: 20
pkt-rate-low: 0
pkt-rate-high: 0

rx-usecs: 0
rx-frames: 1
rx-usecs-irq: n/a
rx-frames-irq: n/a

tx-usecs: 0
tx-frames: 1
tx-usecs-irq: n/a
tx-frames-irq: n/a

rx-usecs-low: n/a
rx-frame-low: n/a
tx-usecs-low: n/a
tx-frame-low: n/a

rx-usecs-high: n/a
rx-frame-high: n/a
tx-usecs-high: n/a
tx-frame-high: n/a

CQE mode RX: n/a  TX: n/a

これを合理的な値(マイクロ秒単位)に設定、設定、およびrx-usecs-low無効rx-usecsにできますadaptive-rx。 (高速ネットワーキングを年中無休で24時間使用できない状況では、ほとんど欠点のないAdaptive RXを使用するのが良い考えでしょう。)

関連情報