8

TL; DR:リアクターのスループットが制限されている可能性はありますか?どうすればわかりますか?io_serviceの実装は(スレッド全体で)どれほど高価でスケーラブルですか?

大量のRAMと高速SSDRAIDを備えたハイパースレッドデュアルクアッドコアXeonマシンで実行されている、超並列アプリケーションがあります。これは、boost::asioを使用して開発されています。

このアプリケーションは、約1,000台の他のマシンからの接続を受け入れ、データを読み取り、単純なプロトコルをデコードし、mmap()を使用してマップされたファイルにデータをシャッフルします。また、アプリケーションはmadvise(WILLNEED)を使用して「将来の」mmapページをプリフェッチするため、ページフォールトでブロックされる可能性は低いですが、念のため、最大300スレッドを生成しようとしました。

これは、Linuxカーネル2.6.32-27-generic(Ubuntu Server x64 LTS 10.04)で実行されています。Gccバージョンは4.4.3で、boost :: asioバージョンは1.40です(どちらもストックUbuntu LTSです)。

vmstat、iostat、topを実行すると、ディスクスループット(TPSとデータボリュームの両方)が1桁の%であることがわかります。同様に、ディスクキューの長さは常にスレッドの数よりもはるかに短いため、I/Oバウンドではないと思います。また、RSSは上昇しますが、数ギグで安定し(予想どおり)、vmstatはページングを表示しないため、メモリに縛られていないと思います。CPUは、ユーザーが0〜1%、システムが6〜7%で一定で、残りはアイドル状態です。ヒント!1つの完全な「コア」(ハイパースレッディングを思い出してください)は、CPUの6.25%です。

64kBを超える未処理の場合、クライアントマシンはTCP送信をブロックし、その事実を報告するため、システムが遅れていることはわかっています。それらはすべてこの事実を報告し続けており、システムへのスループットは、望ましい、意図された、理論的に可能なものよりはるかに少ないです。

私の推測では、私はある種の錠前で争っています。アプリケーションレベルのロックを使用して、変更される可能性のあるルックアップテーブルを保護しているため、これを256のトップレベルのロック/テーブルに分割して、その依存関係を解消しました。しかし、それはまったく役に立たなかったようです。

すべてのスレッドは、1つのグローバルio_serviceインスタンスを通過します。アプリケーションでstraceを実行すると、ほとんどの時間がfutex呼び出しの処理に費やされていることがわかります。これは、イベントベースのio_serviceリアクターの実装に関係していると思います。

リアクターのスループットが制限されている可能性はありますか?どうすればわかりますか?io_serviceの実装は(スレッド全体で)どれほど高価でスケーラブルですか?

編集:私は最初にこの他のスレッドを見つけませんでした。それは私のものと重ならないタグ​​のセットを使用していたからです:-/私の問題はboost::asioreactorの実装で使用される過度のロックである可能性があります。C ++ソケットサーバー-CPUを飽和させることができないを参照してください 。ただし、疑問は残ります。これをどのように証明できますか?そして、どうすればそれを修正できますか?

4

3 に答える 3

2

答えは確かに、最新のboost :: asioでさえ、一度に複数のスレッドからカーネルに入るのではなく、単一のスレッドからepollファイル記述子を呼び出すだけです。同じファイル記述子の通知を受け取ることができる複数のスレッドを使用する場合、スレッドの安全性とオブジェクトの存続期間が非常に不安定になるため、その理由は理解できます。これを(pthreadを使用して)自分でコーディングすると、機能し、単一のコアを超えてスケ​​ーリングします。その時点でboost::asioを使用していません-他の点ではうまく設計されたポータブルライブラリにこの制限があるのは残念です。

于 2011-08-25T06:13:44.743 に答える
2

複数のio_serviceオブジェクト(たとえば、CPUコアごとに)を使用し、それぞれが単一のスレッドで実行されている場合、この問題は発生しないと思います。BoostASIOページのhttpサーバーの例2を参照してください。

サーバーの例2とサーバーの例3に対してさまざまなベンチマークを実行しましたが、前述の実装が最適であることがわかりました。

于 2011-10-13T20:04:54.030 に答える
0

私のシングルスレッドアプリケーションでは、プロファイリングから、プロセッサ命令の大部分がio_service :: poll()によるロックとロック解除に費やされていることがわかりました。BOOST_ASIO_DISABLE_THREADSマクロを使用してロック操作を無効にしました。スレッドの状況によっては、それはあなたにとっても理にかなっているかもしれません。

于 2015-10-31T03:11:56.330 に答える