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を飽和させることができないを参照してください 。ただし、疑問は残ります。これをどのように証明できますか?そして、どうすればそれを修正できますか?