質問
私はいつもそれらが何なのか疑問に思っていました。彼らについて聞くたびに、未来のフライホイールのような装置のイメージが頭の中で踊ります(転がる?)...
彼らは何ですか?
解決
通常のロック (ミューテックス、クリティカル セクションなど) を使用すると、オペレーティング システムはスレッドを待機状態にし、 先制する 同じコア上の他のスレッドをスケジュールすることで実現します。待機時間が非常に短い場合、スレッドは再び CPU 時間を受け取るためにプリエンプションを待機する必要があるため、パフォーマンスが低下します。
さらに、カーネル オブジェクトは、割り込みハンドラーやページングが使用できない場合など、カーネルのすべての状態で使用できるわけではありません。
スピンロックはプリエンプションを引き起こしませんが、他のコアがロックを解放するまでループ (「スピン」) で待機します。これにより、スレッドが失われるのを防ぎます 量子 ロックが解除されたらすぐに続行します。スピンロックのシンプルなメカニズムにより、カーネルはほぼすべての状態でスピンロックを利用できます。
そのため、シングル コア マシンでは、スピンロックは単に「割り込みを無効にする」か、スレッドのスケジューリングを完全に妨げる「IRQL を上げる」ことになります。
スピンロックにより、カーネルは最終的に「ビッグ カーネル ロック」(コアがカーネルに入るときに取得され、終了時に解放されるロック) を回避し、カーネル プリミティブを詳細にロックできるようになり、マルチコア マシンでのマルチ処理が向上し、パフォーマンスが向上します。
編集:という質問が出てきました。「それは、可能な限りスピンロックを使用する必要があるということですか?」そして、私はそれに答えようとします:
先ほど述べたように、スピンロックは、予想される待ち時間がクォンタムよりも短い場合にのみ役立ちます (以下を参照)。ミリ秒)、プリエンプションはあまり意味がありません(例:カーネル オブジェクトは利用できません)。
待ち時間が不明な場合、またはユーザー モードの場合、スピンロックは効率的ではありません。スピンロックが利用可能かどうかを確認している間、待機中のコアで CPU 時間が 100% 消費されます。クォンタムの有効期限が切れるまで、そのコア上で他のスレッドが実行されるのを防ぎます。このシナリオは、カーネル レベルでの短いバーストの場合にのみ実現可能であり、ユーザー モード アプリケーションのオプションである可能性は低いです。
これに対処するSOの質問は次のとおりです。 スピンロック、どれくらい便利ですか?
他のヒント
セイリソースは、ロックで最初のロックを取得する必要があるリソースへのアクセスを望んでいるのスレッドを保護されています。ロックが利用できない場合、ロックが解放されている場合、スレッドは、繰り返しチェックすることがあります。この間スレッドビジー待機、ロックのチェック、CPUを使用しますが、任意の有用な仕事をしていません。このようなロックはスピンロックと呼ばれます。
これはかなり一定の条件が満たされるまでいっているループです。
while(cantGoOn) {};
while(something != TRUE ){};
// it happend
move_on();
するタイプのロックです。 忙しい待ち時間
これは、非常に低レベルのドライバー プログラミングを除いて、アンチパターンとみなされます (「適切な」待機関数の呼び出しの方が、数サイクルの間単にビジー ロックを行うよりもオーバーヘッドが大きくなる場合があります)。
たとえばを参照してください Linux カーネルのスピンロック.
スピンロックは、ロックが利用可能になるまでスレッドが待機しているものです。これは、通常、いくつかの小さな期間内にカーネルオブジェクトを取得する範囲がある場合に、カーネルオブジェクトを取得するオーバーヘッドを回避するために使用されます。
例:
While(SpinCount-- && Kernel Object is not free)
{}
try acquiring Kernel object
あなたはビジー待機ループに入るために安価だと思いますし、代わりにリソースがロックされているときに、ブロッキングのリソースをプールするときスピンロックを使用するとよいでしょう。
はロックが細粒と数が大きい場合にスピニングが有益であり得る(例えば、リンクされたリスト内のノードごとロック)ならびに場合、ロック保持時間が極めて短い常に。一般的には、スピンロックを保持しながら、一つは動的、静的に任意のコードの1のdoesnの「内に電話を派遣すること、コール(インターフェースとvirtualsを)を派遣すること、それ自体が一度に複数のスピンロックを保持し、ブロックすることが何かを呼び出して、ブロックを避ける必要があります自身のT、またはメモリを割り当てる。
これは、スピンロックはパフォーマンス上の理由から、値型であることに注意することも重要です。そのため、1は2つのインスタンス(オリジナルとコピー)を次に可能性の高いアプリケーションの誤った行動につながる互いの完全に独立になるようではない偶然、スピンロックのインスタンスをコピーすることは非常に慎重でなければなりません。スピンロックのインスタンスが周りに渡さなければならない場合、それは、参照することによってではなく値で渡す必要があります。
は一言で言えば、スピンロックはフリースレッドセーフなイディオムを待って、ロックフリーを実現するための命令のような比較原子およびスワップ(CAS)またはテスト・アンド・セットを使用します。このような構造は、マルチコアマシンでうまくスケール。
この条件が満たされるまでの周りのスピンループです。
まあ、はい - 彼らはすぐにスレッドの量子の残りを得ていないので、スピンロック(伝統的なクリティカルセクション対、など)のポイントは、彼らはいくつかの状況(マルチコアシステム...)の下で優れたパフォーマンスを提供することです。
スピンロックは、非ブロック可能と非スリープ可能であり、ロックのタイプです。任意の共有や、重要なリソースのためにスピンロックを取得したい任意のスレッドは、指定されたリソースのロックを取得するまで、CPUの処理サイクルを無駄に、継続的に回転します。スピンロックが取得されると、それはその量子で作業を完了してから、それぞれのリソースを解放してみてください。スピンロックはロックの優先順位が最も高いタイプで、単にそれはノンプリエンプティブなロックの一種である、と言うことができます。