9

「アトミック vs 非アトミック」という概念を頭の中に定着させようとしています。私の最初の問題は、それに関する「現実のアナロジー」を見つけることができなかったことです。アトミック操作または同様のものに対する顧客/レストラン関係のように。

また、アトミック操作がスレッドセーフ プログラミングにどのように組み込まれるかについても学びたいと思います。

このブログ投稿では; http://preshing.com/20130618/atomic-vs-non-atomic-operations/ 次のように言及されています。

共有メモリで動作する操作は、他のスレッドと比較して単一のステップで完了する場合、アトミックです。共有変数でアトミック ストアが実行されると、他のスレッドは変更が半分完了したことを確認できません。共有変数でアトミック ロードが実行されると、ある瞬間に表示された値全体が読み取られます。非アトミックなロードとストアは、これらの保証を行いません。

「他のスレッドは半分完了した変更を観察できない」とはどういう意味ですか?

つまり、スレッドはアトミック操作が完了するまで待機しますか? そのスレッドがその操作についてどのように知っているかはアトミックですか? たとえば、.NET では、フラグを設定して他のスレッドをブロックするオブジェクトをロックするかどうかを理解できます。しかし、アトミックはどうですか?他のスレッドは、アトミック操作と非アトミック操作の違いをどのように認識していますか?

また、上記のステートメントが当てはまる場合、すべてのアトミック操作はスレッドセーフですか?

4

5 に答える 5

18

アトミックとは何か、ブロックとは何かを少し明確にしましょう。原子性とは、操作が完全に実行され、そのすべての副作用が表示されるか、またはまったく実行されないことを意味します。したがって、他のすべてのスレッドは、操作の前または後の状態を見ることができます。ミューテックスによって保護されたコードのブロックもアトミックです。操作とは呼びません。アトミック操作は特別な CPU 命令であり、概念的にはミューテックスによって保護された通常の操作に似ています (ミューテックスが何であるかを知っているので、アトミック操作を使用して実装されているという事実にもかかわらず、ミューテックスを使用します)。CPU がアトミックに実行できる操作のセットは限られていますが、ハードウェア サポートにより非常に高速です。

スレッド ブロックについて議論するときは、ミューテックスによって保護されたコードの実行にかなりの時間がかかる可能性があるため、通常、会話にミューテックスが含まれます。したがって、スレッドはミューテックスを待機していると言えます。アトミック操作の場合も状況は同じですが、それらは高速であり、通常はここで遅延を気にしないため、「ブロック」と「アトミック操作」という言葉を一緒に聞くことはあまりありません。

つまり、スレッドはアトミック操作が完了するまで待機しますか?

はい、それは待ちます。CPU は、変数が配置されているメモリ ブロックへのアクセスを制限し、他の CPU コアは待機します。パフォーマンス上の理由から、ブロックはアトミック操作の間でのみ保持されることに注意してください。CPU コアは、読み取り用の変数をキャッシュできます。

そのスレッドがその操作についてどのように知っているかはアトミックですか?

特別な CPU 命令が使用されます。特定の操作をアトミックに実行するようにプログラムに記述しているだけです。

追加情報:

アトミック操作には、さらにトリッキーな部分があります。たとえば、最新の CPU では通常、プリミティブ型のすべての読み取りと書き込みはアトミックです。ただし、CPU とコンパイラはそれらを並べ替えることができます。したがって、一部の構造体を変更し、それが変更されたことを示すフラグを設定することは可能ですが、構造体が実際にメモリにコミットされる前に、CPU が書き込みを並べ替えてフラグを設定します。アトミック操作を使用する場合、通常、望ましくない並べ替えを防ぐために追加の作業が行われます。詳細を知りたい場合は、メモリバリアについて読む必要があります。

単純なアトミック ストアと書き込みはあまり役に立ちません。アトミック操作を最大限に活用するには、もっと複雑なものが必要です。最も一般的なのは CAS - 比較と交換です。変数を値と比較し、比較が成功した場合にのみ変更します。

于 2016-09-30T16:36:36.970 に答える
1

「アトミック」であることは、実装 (一般的に言えば、ハードウェアまたはコンパイラ) によって強制される操作に適用される属性です。実際の例えとして、銀行口座などのトランザクションを必要とするシステムに注目してください。ある口座から別の口座への送金には、ある口座からの引き出しと別の口座への入金が含まれますが、通常、これらはアトミックに実行する必要があります。

したがって、質問の類推を続けます。

「他のスレッドは半分完了した変更を観察できない」とはどういう意味ですか?

これは、一方のアカウントから引き出しが行われ、別のアカウントには入金されていない状態で、2 つのアカウントを監視できるスレッドがなかったことを意味します。

マシン用語では、あるスレッドの値のアトミック読み取りでは、別のスレッドによるアトミック書き込みの前のビットと、同じ書き込み操作の後のビットの値が表示されないことを意味します。単一の読み取りまたは書き込みよりも複雑なさまざまな操作もアトミックにすることができます。たとえば、「比較とスワップ」は、変数の値をチェックし、それを 2 番目の値と比較し、別の値に置き換える、一般的に実装されているアトミック操作です。比較された値が原子的に等しかった場合の値 - たとえば、比較が成功した場合、別のスレッドが操作の比較部分と交換部分の間に異なる値を書き込むことはできません。別のスレッドによる書き込みは、アトミックなコンペアアンドスワップの前または後に完全に実行されます。

あなたの質問のタイトルは次のとおりです。

アトミック操作は他のスレッドをブロックしますか?

「ブロック」の通常の意味では、答えはノーです。あるスレッドでのアトミック操作は、別のスレッドで実行を停止させることはありませんが、ライブロックの状況を引き起こしたり、進行を妨げたりする可能性があります。

つまり、スレッドはアトミック操作が完了するまで待機しますか?

概念的には、待つ必要がないことを意味します。操作は完了したか、完了していません。決して中途半端ではありません。実際には、ミューテックスを使用してアトミック操作を実装できますが、パフォーマンスが大幅に低下します。多くの (ほとんどではないにしても) 最新のプロセッサは、ハードウェア レベルでさまざまなアトミック プリミティブをサポートしています。

また、上記のステートメントが当てはまる場合、すべてのアトミック操作はスレッドセーフですか?

アトミック操作を構成すると、アトミックではなくなります。つまり、1 つのアトミックなコンペア アンド スワップ操作の後に別のオペレーションを実行できます。2 つのコンペア アンド スワップは個別にアトミックですが、割り切れます。したがって、同時実行エラーが発生する可能性があります。

于 2016-09-30T16:21:32.567 に答える