web-dev-qa-db-ja.com

`std :: mutomic`との同期は、` std :: atomic(memory_order_seq_cst) `よりも遅いですか?

ミューテックスでアトミックを使用する主な理由は、ミューテックスは高価ですが、atomicsのデフォルトのメモリモデルがmemory_order_seq_cstであるため、これは同じくらい高価ではないのですか?

質問:ロックを使用する並行プログラムは、並行ロックのないプログラムと同じくらい速くできますか?

もしそうなら、アトミックにmemory_order_acq_relを使いたくない限り、努力する価値はないかもしれません。


編集:私は何かが足りないかもしれませんが、各ロックは完全なメモリバリアでなければならないので、ロックベースはロックフリーよりも速くできません。ただし、ロックフリーを使用すると、メモリのバリアよりも制限が少ない手法を使用できます。

だから私の質問に戻って、ロックフリーはデフォルトのmemory_modelの新しいC++ 11標準に基づくロックよりも速いですか?

「ロックフリー> =パフォーマンスで測定したときにロックベース」は正しいですか? 2つのハードウェアスレッドを想定します。


編集2:私の質問は進捗の保証についてではなく、おそらく「ロックフリー」を文脈外で使用しています。

基本的に、共有メモリを備えた2つのスレッドがあり、必要な唯一の保証は、一方のスレッドが書き込みを行っている場合、もう一方のスレッドが読み書きできない場合、単純なアトミックcompare_and_swap操作で十分であると想定していますmutexをロックするよりも高速です。

1つのスレッドが共有メモリにアクセスすることさえない場合、理由もなく何度も何度もロックとロック解除を繰り返すことになりますが、アトミック操作では毎回1 CPUサイクルしか使用しません。

コメントに関しては、競合がほとんどない場合、スピンロックとミューテックスロックは大きく異なります。

33
jaybny

ロックフリープログラミングは、約進行保証:最も強いものから最も弱いものまで、wait-freelock-freeobstruction-free、およびblocking

保証は高価であり、代償を伴います。保証が多ければ多いほど、支払う金額も多くなります。一般に、ブロッキングアルゴリズムまたはデータ構造(たとえば、ミューテックスを使用)には最大の自由度があるため、潜在的に最速です。もう一方の極端な待機なしアルゴリズムでは、すべてのステップでアトミック操作を使用する必要があり、はるかに遅くなる可能性があります。

ロックを取得することは実際にはかなり安価です。そのため、件名を深く理解しなければ、心配することはありません。さらに、ミューテックスを使用したブロッキングアルゴリズムは、読み取り、書き込み、および推論がずっと簡単です。対照的に、最も単純なロックフリーのデータ構造でさえ、それぞれが1つまたは複数の博士号を取得する価値のある長く集中した研究の結果です。

簡単に言えば、ロックまたは待機なしのアルゴリズムは、最悪のレイテンシを平均レイテンシとスループットと交換します。すべてが遅くなりますが、非常に遅くなることはありません。これは非常に特殊な特性であり、非常に特殊な状況(リアルタイムシステムなど)でのみ役立ちます。

53
Kerrek SB

ロックは、単純なアトミック操作よりも多くの操作を必要とする傾向があります。最も単純なケースでは、memory_order_seq_cstはロックの約2倍の速度になります。これは、ロックの実装で最低2つのアトミック操作が必要になる傾向があるためです(1つはロック、もう1つはロック解除)。多くの場合、それ以上の時間がかかります。ただし、メモリの順序を活用し始めると、受け入れられる同期が少なくなるので、はるかに速くなります。

また、「ロックアルゴリズムは常にロックフリーアルゴリズムと同じくらい高速である」とよく目にします。これはやや本当です。基本的な考え方は、最速のアルゴリズムがたまたまロックフリーである場合、ロックフリーの保証がない最速のアルゴリズムも同じアルゴリズムであるということです!ただし、最速のアルゴリズムがロックを必要とする場合、ロックフリーの保証を要求するものはより遅いアルゴリズムを見つけなければなりません。

一般に、ロックフリーアルゴリズムは、いくつかの低レベルアルゴリズムに見られます。ここでは、特殊なオペコードを活用するパフォーマンスが役立ちます。他のほとんどすべてのコードでは、ロックは十分なパフォーマンス以上であり、はるかに読みやすくなっています。

2
Cort Ammon