4

さまざまなネットワーク トラフィックを持つリアルタイムの組み込み Linux アプリケーションを構築しています。一連のトラフィックのうち、2 つの接続はタイム クリティカルです。1 つは入力データ用で、もう 1 つは出力データ用です。私のアプリケーションでは、このトラフィックが他のタイム クリティカルでないトラフィックよりも優先される必要があります。

私は2つのことを気にしています:

  1. これら 2 つの接続の過負荷によりドロップされるパケットの数を最小限に抑えます。
  2. これら 2 つの接続で、デバイス (入力から出力) を介したレイテンシを最小限に抑えます。

私は Linux トラフィック制御について (ある程度!) 理解を深めており、送信されるデータの優先度はリモート デバイスが担当するため、主に送信トラフィックに適用されることを理解しています。アプリケーションをリアルタイム プロセスとしてセットアップし、アプリケーションを実行する優先度に関連する問題に取り組みました。

私は今、tcのセットアップに着手します。私のテストケースでは、これが私が使用するものです:

tc qdisc add dev eth0 root handle 1: prio bands 3 priomap 2 2 2 2 2 2 2 0 2 2 2 2 2 2 2 2
tc qdisc add dev eth0 parent 1:1 handle 10: pfifo
tc qdisc add dev eth0 parent 1:2 handle 20: pfifo
tc qdisc add dev eth0 parent 1:3 handle 30: pfifo

基本的には、優先度 7 のすべてのトラフィックを帯域 0 で送信し、その他のすべてのトラフィックを帯域 2 で送信するということです。

まず、私の予想を確認してみましょう。私が予想しているのは、優先度 7 のトラフィックは、他の優先度のトラフィックよりも常に先に送信される必要があるということです。これにより、そのようなトラフィックの遅延は、ボックス上の他のトラフィックの影響を比較的受けなくなりますよね? 私の mtu は 1500 に設定されており、インターフェイス経由で約 10 MB/秒を取得しています。バンド 2 トラフィックによって生じるバンド 0 の最大追加レイテンシは、1 パケット (<=1500 バイト)、または 150 マイクロ秒 (1500 バイト / 10 M バイト/秒 = 150 マイクロ秒) です。

これが私のテスト設定です:

2 つの Linux ボックス。ボックス 1 は、入力データをエコーする TCP サーバーを実行しています。ボックス 2 はボックス 1 に接続し、TCP 経由でパケットを送信し、遅延 (送信時間から受信時間) を測定します。

ボックス Linux ボックスに同じ tc セットアップを使用します。

アプリケーション (サーバーとクライアントの両方) で、次のようにソケットに SO_PRIORITY を設定しました。

int so_priority = 7;
setsockopt(m_socket.native(), SOL_SOCKET, SO_PRIORITY, &so_priority, sizeof(so_priority));

tc を使用して、トラフィックが帯域 0 を通過し、他のすべてのトラフィックが帯域 2 を通過することを確認します。

tc -s qdisc ls dev eth0

問題は次のとおりです。他にトラフィックがない場合、500 us の範囲の遅延が見られます。他のトラフィック (たとえば、100 MB のファイルをコピーする scp ジョブ) がある場合、レイテンシーは 10 ミリ秒以上に跳ね上がります。本当に奇妙なのは、私が行った tc の作業がまったく影響を与えていないことです。実際、帯域を交換すると (つまり、すべてのトラフィックが優先度の低い帯域 2 を通過し、その他のトラフィックが帯域 1 を通過します)、遅延に違いは見られません。

私が予想していたのは、ネットワーク上に他のトラフィックがある場合、10 ミリ秒ではなく、約 150 マイクロ秒の遅延の増加が見られるということです! ところで、ボックスに他の (非リアルタイム優先) プロセスをロードしても、レイテンシーや他のインターフェイスのトラフィックに影響しないことを確認しました。

もう 1 つの注目すべき点は、mtu を 500 バイトに下げると、レイテンシーが約 5 ミリ秒に減少することです。それでも、これは無負荷の場合よりも一桁悪いです。また、なぜ mtu を変更するとそれほど影響を受けるのに、tc を使用してプライオリティ キューイングを設定しても効果がないのですか?

tc が役に立たないのはなぜですか? 私は何が欠けていますか?

ありがとう!

エリック

4

3 に答える 3

0

ネットワークの残りの部分については何も言わなかったが、スループットを最適化するために通常は長いキューがあるアップストリームルーターでキューに到達していると思います。これを修正する最善の方法は、優先キューをアップストリーム帯域幅のすぐ下の帯域幅を持つシェーパーにフィードすることです。これにより、バルク優先度のパケットが外部ルーターではなくボックス内でキューに入れられ、期待どおりに優先度の高いパケットがキューの先頭にジャンプできるようになります。

于 2010-09-21T01:06:43.493 に答える
0

prio ファシリティは、パケットの送信時に利用可能な最も優先度の高いパケットを単純に送信します (通常、送信待ちのパケットがない場合を除き、前のパケットが送信されるとすぐに)。

テストは、各マシンの適切なプログラムのプロセスによってキューに配置されたパケットと、各マシンのポートから取得された受信パケットに依存しています。

プロセスがいずれかのマシンに到達する時間に影響を与えるスケジューリングの遅延は、キューにメッセージを配置したり、キューからメッセージを取得して処理したりするプロセスの機能に影響を与える可能性があります。これをテストするために少なくとも 1 台のマシンをロードしたようですが、私の経験では、マシンのロードはこのように測定されたレイテンシーに (マイクロ秒ではなくミリ秒のオーダーで) 確実に影響するため、両方のマシンをロードしてこれを繰り返す価値があるかもしれません。優先度の高いタスクで。

他に確認する必要があるのは、レイテンシーの測定に使用しているタイムスタンプです。それは、エコー メッセージがクライアント マシンで実際に受信された時間か、プログラムがそれを処理した時間かです。後者の場合、ネットワーク遅延だけでなく、メッセージが受信されてからプログラムがプロセッサのスライスを取得し、時間を確認するポイントに到達するまでの時間も測定しています - http://wiki.wiresharkを参照してください.org/タイムスタンプ.

余談ですが、リアルタイム OS のようなメカニズムがなければ、マイクロ秒レベルの応答性を保証することはできないと思います。一方、アプリケーションが VoIP の場合は、通常、最大約 200 ミリ秒の遅延で問題ありません。

于 2010-11-01T14:54:51.317 に答える
0

パケットをキャプチャして、IP ヘッダーの TOS 値が変更されているかどうかを確認しようとしましたか?

SO_PRIORITY を使用するには、Linux 2.6.39 以降が必要です。

代わりに IP_TOS を変更する必要があります。

設定する必要があります:

int iptos_precedence = 0xc0;
if (setsockopt(sock_fd, IPPROTO_IP, IP_TOS, &iptos_precedence, sizeof(iptos_precedence)) < 0) {
           //print errno (or something like that)
}
于 2014-04-01T09:47:06.313 に答える