web-dev-qa-db-ja.com

C ++でロックフリーマップを実装することは可能ですか?

ネットワークアプリケーションベースのC/Sを開発していますが、std :: mapに追加するロックが多すぎて、サーバーのパフォーマンスが低下していることがわかりました。

ロックフリーマップを実装できるかどうか疑問に思います。実装できる場合は、どうすればよいでしょうか。そこにオープンソースコードはありますか?

編集:実際には、std :: mapを使用してソケット情報を格納し、ソケットファイルの説明に基づいてカプセル化を行い、IPアドレス、ポート、ソケットタイプ、tcpまたはudpなどの他の必要な情報を含めました。

要約すると、世界地図には

map<int fileDescriptor, socketInfor*> SocketsMap, 

次に、データの送信に使用されるすべてのスレッドがSocketsMapにアクセスする必要があり、SocketsMapからの読み取りまたはSocketsMapへの書き込みの前にミューテックスを追加する必要があります。したがって、SocketsMapに追加されるロックが非常に多いため、アプリケーション全体の同時実行レベルが大幅に低下します。

同時実行レベルの問題を回避するために、2つの解決策があります。1。各socketInfor *を個別に保存します。2。ある種のロックフリーマップを使用します。

このソリューションに必要なコードの変更はソリューション1の変更よりもはるかに少ないため、ある種のロックフリーマップを見つけたいと思います。

18
Steve

実際には方法がありますが、私自身は実装していませんが、著名なC++エキスパートのAndreiAlexandrescuによる ハザードポインターを使用したロックフリーマップ に関する論文があります。

15
Ylisar

はい、「Split-Ordered Lists」の概念を使用して、C++で Lock-Free Unordered Mapdocs )を実装しました。これは自動拡張コンテナであり、ABAの問題なしに64ビットCASで数百万の要素をサポートします。パフォーマンスに関しては、 beast です(5ページを参照)。それは 広範囲にテストされた 何百万ものランダムな操作でテストされました。

3
Qarterd

HashMapが適していますか? Intel Threading Building Blocks を見てください。興味深い並行マップがあります。ロックフリーかどうかはわかりませんが、特にロックフリーではなく、優れたマルチスレッドパフォーマンスに関心があることを願っています。また、チェックすることができます CityHash lib

編集:

実際、TBBのハッシュマップはロックフリーではありません

2
Andriy Tylychko

C++ 11を使用している場合は、 facebook/folly のAtomicHashMapを見ることができます。

2
nkout

誰もそれについて言及していないことに驚いていますが、Click Cliffは待機なしの Javaのハッシュマップ を実装しました。これはC++に移植できると思います。

1
Adam Kurkiewicz

楽観的設計 または トランザクションメモリを使用してマップを実装できます。

このアプローチは、2つの操作が同時にマップをアドレス指定し、1つがマップの構造を変更する可能性が比較的小さく、毎回ロックのオーバーヘッドが必要ない場合に特に効果的です。

ただし、ときどき衝突が発生し、何らかの方法で衝突が発生する必要があります(通常は、最後の安定状態にロールバックして操作を再試行します)。

ハードウェアが十分なアトミック操作をサポートしている場合-これは コンペアアンドスワップ(CAS) で簡単に実行できます-参照のみを変更します(マップを変更するたびに、のコピーで作業しますオリジナルではなくマップし、コミットした場合にのみプライマリとして設定します)。

1
amit