web-dev-qa-db-ja.com

アトミック変数はロックフリーですか?

C++ 11のatomic<>などのアトミック変数について話すとき、それはロックフリーですか?それともロックフリーネスは何か違うのですか?アトミック変数でキューを管理する場合、ロックフリーキューよりも遅くなりますか?

40
pythonic

標準では、アトミックオブジェクトがロックフリーであるかどうかは指定されていません。タイプTのロックフリーアトミック操作を提供しないプラットフォームでは、_atomic<T>_オブジェクトはミューテックスを使用して実装できますが、これはロックフリーではありません。その場合、実装でこれらのオブジェクトを使用するコンテナもロックフリーにはなりません。

標準では、_atomic<T>_変数がロックされていないかどうかを確認する方法が提供されています。var.is_lock_free()またはatomic_is_lock_free(&var)を使用できます。これらの関数は、特定のプログラムの実行時に、同じ型Tに対して常に同じ値を返すことが保証されています。 intなどの基本的なタイプの場合、そのタイプへのロックフリーのアトミックアクセスが利用可能かどうかを指定するマクロも提供されます(例:_ATOMIC_INT_LOCK_FREE_)。

37
interjay

Lock-freeは通常、複数のスレッド間で共有されるデータ構造に適用され、同期メカニズムはnot相互排除です。その意図は、すべてのスレッドがミューテックスでスリープするのではなく、何らかの進歩を続けることです。

atomic<T>変数はロックを使用しませんが(少なくともTはプラットフォームでネイティブにアトミックな場合)、上記の意味でロックフリーではありません。ロックフリーコンテナの実装でそれらを使用する可能性がありますが、それだけでは十分ではありません。

たとえば、atomic<queue<T>>が突然通常のstd::queueをロックフリーのデータ構造にすることはありません。ただし、メンバーがatomicである、完全にロックフリーのatomic_queue<T>を実装することもできます。

atomic<int>がネイティブにアトミックであり、プラットフォームのロックでエミュレートされていなくても、それはlock-freeにはなりません。面白い方法。プレーンintは、この意味でalreadyロックフリーです:atomic<>ラッパーは、メモリの順序を明示的に制御します。ハードウェア同期プリミティブへのアクセス。

11
Useless

マーケティングとクールな要素はさておき、マジックC++構文(茶色)シュガーが直接バスロックまたはミューテックス(バスロックに依存しているかもしれませんが、コメンテーターが言及しているように、より効率的な方法でそれを行うためのOS内部の利点)、またはシングルプロセッサアーキテクチャで実行するのに不運な場合はまったく何もしません。

Mutexは意味的にロックがすでに解放されています。それらは、スケジューラーの素晴らしさ、つまり優先順位の反転処理と再入可能性の観点から、あなたが夢見るかもしれないすべてのものを実装しています。ミューテックスであなたができないデッドロック(まあ、あなたが非常に一生懸命に努力した場合、そうかもしれませんが、変数の保護に関する限り、あなたはしません) 、およびmutexを使用するとnotは、バスロックされた変数よりも他のプロセスまたはオペレーティングシステムに顕著な副作用があります。

唯一の違いは、プログラマーが(設計上または誤って)不適当な時間mutexを保持する可能性がある一方で、同様に無能なプログラマーが「待機なし」の変数をポーリングして、致命的な同じ結果を得る可能性があることです。ミューテックスの誤用よりもシステム全体に大きな負荷をかけるバスの速度低下(OK、以前の [〜#〜] bsod [〜#〜]への言及 は未成年でした挑発、しかし私はまだいくつかのドライバーがバスの激しい競合にとても親切に反応しないかもしれないと疑っています)。とにかく、この問題は、mutex呼び出しが適度に少量のメモリへの線形アクセスにラップされるとすぐに解決されます。

「ロックフリー」はワナビーのハードボイルドプログラマに夢を売ります。マルチプロセッサバスが実際にlockingに依存しているメカニズムがそれと呼ばれていることは、かなり面白いと思います。

「ロックフリー」変数アクセスは、バスキャッシュシステムを無効にし、バスアクセスのスケジューリングを禁止し、平均的なマルチプロセッサバスが適切なジョブを実行できるようにするすべてのメカニズムを無効にして、ハードウェアを苦しめます。
「ロックフリー」マジック変数にアクセスするたびに、バスコントローラーの歯車に砂を一握り入れます。

他の同時アクセスメカニズムと同様に、バスロックされた変数(申し訳ありませんが、 "ロックのない変数"を意味します)はコストが高く、潜在的なマイナスの副作用があります 予測または診断さえも非常に難しい

ミューテックスと同じようにこれらの新しい光沢のあるおもちゃを使用している限り、つまり、非常にまばらで、いくつかの正当な理由がある場合に限り(そして、いいえ、非常にクールなMrウェイトフリーを演じることはそれらの1つではありません)、問題ありません。

しかし、バスロックをあちこちに散らし始めた場合、または(God forbids!)pollingバスロックされた変数を適切な同期オブジェクトの安価で簡単な置き換えとしてウェイトフリー氏は、「3つの簡単なステップで独自の自家製スピンロックを醸造する」と呼ぶかもしれませんが、コードが実行する最先端のハードウェアを1995年頃のペンティアムIエミュレーターに変えるしかありません。

1
kuroi neko