3

次のような C++ ネットワーク アプリケーションを作成する予定です。

  1. 私は単一のスレッドを使用して、TCP 接続を受け入れ、それらからデータを読み取ります。これを行うために epoll/select を使用する予定です。データは、jemalloc などのアリーナ アロケータを使用して割り当てられたバッファに書き込まれます。
  2. プロトコル メッセージを形成するのに十分なデータが 1 つの TCP クライアントから得られると、データはリング バッファにパブリッシュされます。リング バッファ構造には、接続用の fd と、関連データを含むバッファへのポインタが含まれます。
  3. ワーカー スレッドは、リング バッファーからのエントリを処理し、結果データをクライアントに送信します。各イベントを処理した後、ワーカー スレッドは実際のデータ バッファーを解放して、再利用できるようにアリーナ アロケーターに返します。

パブリッシャーが、それによって書き込まれたデータをワーカー スレッドから見えるようにする方法の詳細は省きます。

したがって、私の質問は次のとおりです。この種の動作、つまりオブジェクトをあるスレッドに割り当て、別のスレッドで解放することを最適化するアロケーターはありますか?

スレッド アフィニティ化されたアリーナではないアリーナにメモリを返すためにロックを使用する必要があることを特に心配しています。また、プロデューサー スレッドとワーカー スレッドの両方が同じリージョンに書き込むため、偽共有も心配です。jemalloc または tcmalloc はどちらもこれを最適化していないようです。

4

2 に答える 2

3

マルチスレッド アプリケーション用に高度に最適化されたアロケーターを実装する道をたどる前に、まず標準のnewanddelete演算子を実装に使用する必要があります。アプリケーションを正しく実装したら、プロファイリングによって発見されたボトルネックに対処することができます。

new標準とアロケーターがアプリケーションのボトルネックであることが明らかな段階にdelete達した場合、私が使用したアプローチは次のとおりです。

前提:スレッドの数は固定されており、静的に作成されます。

  • 各スレッドには独自のアリーナがあります。
  • アリーナから取得された各オブジェクトには、元のアリーナへの参照があります。
  • 各アリーナには、スレッドごとに個別のガベージ リストがあります。
  • スレッドがオブジェクトを解放すると、元のアリーナに戻りますが、スレッド固有のガベージ リストに配置されます。
  • アリーナを実際に所有するスレッドは、そのガベージ リストを実際の空きリストとして扱います。
  • アリーナを所有するスレッドは定期的にガベージ コレクション パスを実行し、オブジェクトを他のスレッド ガベージ リストから実際の空きリストにフォールドします。

「定期的な」ガベージ コレクション パスは、必ずしも時間ベースである必要はありません。たとえば、ガベージのサブセットを割り当てごとに取得して解放することができます。

于 2013-10-02T23:05:36.873 に答える