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