5

ローカルホストでTCPソケット通信のスループットを最大化するC++サーバー/クライアントを作成したいと思います。準備として、iperfを使用して、i7MacBookProの最大帯域幅を調べました。

------------------------------------------------------------
Server listening on TCP port 5001
TCP window size:  256 KByte (default)
------------------------------------------------------------
[  4] local 127.0.0.1 port 5001 connected with 127.0.0.1 port 51583
[  4]  0.0-120.0 sec   329 GBytes  23.6 Gbits/sec

微調整なしで、iprefは私が少なくとも23.2GBit/秒に達することができることを私に示しました。次に、独自のC ++サーバー/クライアント実装を行いました。完全なコードはここにあります:https ://gist.github.com/1116635

そのコードは、基本的に、読み取り/書き込み操作ごとに1024バイトのint配列を転送します。したがって、サーバー上の送信ループは次のようになります。

   int n;

   int x[256];

   //fill int array
   for (int i=0;i<256;i++)
   {
       x[i]=i;
   }

   for (int i=0;i<(4*1024*1024);i++)
   {
       n = write(sock,x,sizeof(x));
       if (n < 0) error("ERROR writing to socket");
   }

クライアントでの受信ループは次のようになります。

int x[256]; 

for (int i=0;i<(4*1024*1024);i++)
{
    n = read(sockfd,x,((sizeof(int)*256)));
    if (n < 0) error("ERROR reading from socket");
}

見出しで述べたように、これを実行すると(-O3でコンパイル)、実行時間は約3 GBit/sになります。

./client 127.0.0.1 1234
Elapsed time for Reading 4GigaBytes of data over socket on localhost: 9578ms

どこで帯域幅を失うのですか、何が間違っているのですか?繰り返しになりますが、完全なコードはここで見ることができます:https ://gist.github.com/1116635

どんな助けでも大歓迎です!

4

4 に答える 4

5
  • より大きなバッファを使用する (つまり、ライブラリ/システム コールを少なくする)
  • 非同期 API を使用する
  • ドキュメントを読んでください (読み取り/書き込みの戻り値は単なるエラー状態ではなく、読み取り/書き込みのバイト数も表します)
于 2011-07-31T09:44:00.413 に答える
3

を使用strace -f iperf -s localhostして、iperfの動作が異なることを確認できます。あなたよりもかなり大きなバッファ(2.0.5で131072バイトの大きさ)を使用しているようです。

また、iperf複数のスレッドを使用します。CPUコアが4つある場合、クライアントとサーバーで2つのスレッドを使用すると、パフォーマンスが約2倍になります。

于 2011-07-31T09:50:49.080 に答える
3

私の以前の答えは間違っていました。私はあなたのプログラムをテストしました。結果は次のとおりです。

  • 元のクライアントを実行すると、0m7.763s
  • 4 倍の大きさのバッファを使用すると、次のようになります。0m5.209s
  • 元の8倍のバッファを使用して取得0m3.780s

私はクライアントを変更しただけです。サーバーも変更すると、パフォーマンスがさらに低下する可能性があると思います。

私があなたとは根本的に異なる結果を得たという事実 ( 0m7.763svs 9578ms) は、実行されたシステム コールの数が原因であることも示唆しています (プロセッサが異なるため..)。パフォーマンスをさらに向上させるには:

  • スキャター ギャザー I/O (readvおよびwritev)を使用する
  • ゼロコピー メカニズムを使用する: splice(2)sendfile(2)
于 2011-07-31T10:06:45.817 に答える
1

本当に最大のパフォーマンスを得たい場合はmmap+splice/sendfileを使用し、localhost 通信には unix ドメイン ストリーム ソケット ( AF_LOCAL) を使用します。

于 2011-07-31T10:48:51.230 に答える