5

std::unordered_map複数のスレッドから非常に読み取り負荷の高いワークロードを受けている があります。同期には astd::mutexを使用できますが、同時読み取りは問題ないはずなので、boost::shared_mutex代わりに a を使用したいと考えました。パフォーマンスの向上をテストするために、最初にマップに一連の値を事前入力してから、一連のスレッドに読み取りテストを実行させます。

for (int i = 0; i < iters; ++i) map.count(random_uint(0, key_max));

によって保護されている粗いロックの実装と、countによって保護されstd::lock_guard<std::mutex>ている共有ロックの実装に対して、これを実行しboost::shared_lock<boost::shared_mutex>ます。

GCC 6.1.1 を搭載した私の Arch Linux x86_64 システムでは、boost::shared_lockバージョンが常に遅くなります! MSVC 2013 を搭載した友人の Windows 10 システムでboost::shared_lockは、常に高速です。 コンパイル可能な完全なコードは github にあります: https://github.com/silverhammermba/sanity

編集

これはプラットフォーム固有の問題のようです。上記を参照。他の誰かがこのコードをビルドして実行し、正の出力 (shared_lock高速) または負の出力 (もちろんミューテックスの方が高速) を見たかどうか、および使用しているプラ​​ットフォームを報告していただければ幸いです。

4

2 に答える 2

10

Linuxでは「次善」であることboost::shared_mutexがわかりました。

'pthread' の boost::shared_mutex の現在の (boost 1.59 時点での) 実装は、内部ミューテックスの状態を保護するために重いミューテックスを使用しているため、かなり最適ではありません... [アクセスの同時実行性が高い場合] 共有ミューテックスは事実上排他的です。

後押しと、それが奪った私の人生の何時間も万歳。

于 2016-05-18T17:27:21.380 に答える
-3

いくつかのメモ:

  1. データ構造の競合が激しい場合は、ロックフリーの実装で同じデータ構造を使用することを強くお勧めします

  2. リーダー/ライター ロックは通常、読み取りが一般的で、書き込みがまれな場合にパフォーマンスを向上させます。哲学的に言えば、ロックが他のスレッドが読み取りモードまたは書き込みモードでロックをキャッチしたかどうかを判断する必要がある場合、ロックが解放されるのを単に待つよりも遅くなります。したがって、読み取りが一般的で書き込みがまれな場合、他のスレッドはブロックされていません。書き込みが頻繁に行われる場合、スレッドがブロックされるだけでなく、何をどのようにロックしているかを把握するために追加のロジックを実行する必要があります。

したがって、夏の例では、ロックを悪い方法で使用しています。また、パフォーマンスに同意する場合は、ロックフリープログラミングを使用してください。

于 2016-05-18T15:13:07.707 に答える