0

ネットワーク プロジェクトの一環として、ネットワーク プログラムを作成しています。このプログラムは、一連のパケット (berkely ソケット API を使用した通信に使用される TCP) を生成し、それを特定のポートに送信して、返される応答を測定します。プログラムは完全に正常に動作しますが、プログラムが実際に生成するデータ レートのようなバックエンド計算を少し行いたいと考えていました。私がやろうとしたことは、パケットを送信するコードのルーチンの前後の時間を測定し、合計データをその時間で割ったことです。パケットは 82 バイトなので:

799 x 82 x 8 = 524144 ビット。測定された時間は = 0.0001 秒なので、データ レートは 524144 / 0.0001 = 5.24 Gbps です。

これが私が試したコードです:

struct timeval start,end;

double diffTime (struct timeval* start, struct timeval* end)
{
  double start_sec = ((double) start->tv_sec) + (double) start->tv_usec / 1000000.00;
  double end_sec = ((double) end->tv_sec) + (double) end->tv_usec / 1000000.00;
  return (end_sec - start_sec);
}
while(1){
gettimeofday(&start, NULL);  // getting start time

*/ Call packet sending routine */

gettimeofday(&end, NULL);

printf("Time taken for sending out a batch is %f secs\n", diffTime(&start,&end)); 
}

問題に正しくアプローチしているかどうかを確認したかったのです。また、これが正しい方法である場合、実際にどのくらいの速度でパケットがワイヤから出ているか、つまりイーサネット インターフェイスからのパケットの実際の物理速度を調べる方法はありますか? プログラムで計算したパケット レート (ユーザー モードであり、ユーザー/カーネル バリアがシステム コールでトラバースされるため、はるかに遅くなると予想されます) と実際のパケット レートの差を見積もることはできますか? すべての助けに感謝します。

ありがとう。

4

1 に答える 1

1

それはあなたが望むものではないと思います。あなたが持っているものはあなたに情報を与えますが、おそらくそれを改善する方法の指標にはなりません.

通常、私が心配しているのは、ソケットの送信/受信関係におけるヒッチングのレイテンシーを測定することです。これには通常、sends() の間に費やす時間、または何らかの形式の recv() で待機する時間を測定することが含まれます。

通常、注意すべき点がいくつかあります。送信を収集してバッファリングするためにネットワーク層に依存していますか? それとも、データを送信したい場合にのみバッファリングして送信を行っていますか? 後者の場合、通常 nagle バッファリングをオフにしたい (setsockopt と TCP_NODELAY を参照) - ただし、コードが後退しないように注意してください。

次はバッファリングです。おそらく、データがソケット バッファリングに到達するまでの時間を測定しているはずです。これはほぼ瞬時です。応答パケットの ack/coordination を使用してストリーミングしている場合、これは長期間にわたって平均化されます。setsockopt() と SO_RCVBUF/SO_SNDBUF でバッファリングをいじることができます。

もう少し先まで行きます。パフォーマンスのために物理ネットワークではなくコードを測定していて、可能な限り大きなブロックでパケットを送受信している場合、通常チェックすることがさらに 2 つあります。

  1. ACK タイプのプロトコルはありますか。コードは基本的にパターンで送受信します。もしそうなら、その遅延が最大の問題になる可能性があります. これを解決するには、複数の保留中のリクエストを個別にストリーミングできるようにすることから、スライディング ウィンドウを実装することまで、さまざまな方法があります。主なアイデアは、データの流れを妨げないことです。

  2. 最後に、recv() を扱っている場合、スレッド/プロセスごとに 1 つのソケット関係を処理したいだけでない限り、通常は recv でブロックしたくありません。古い学校の解決策は select() であり、それは妥当なスケーラビリティのためにまだ実行可能です。大規模なソリューションについては、epoll(linux)、kevents(osx)、または IOCP(windows) を検討します。これらにより、より多くの簿記と (場合によっては) スレッド プーリングを OS に戻すことができます。これは、問題が実際にこの NIC から送り出せるデータ量に関するものである場合に必要な場所です。ただし、複数の接続を処理する場合を除き、ほとんど必要ありません。

あなたが本当に求めていたことを見逃していたら申し訳ありませんが、一般的な問題をカバーしようとしました.

于 2012-03-04T19:22:58.907 に答える