スピンロックはポーリングとどう違うのですか?


41

スピンロックとポーリングは同じものですか?

ウィキペディア:

スピンロックは、ロックを取得しようとするスレッドに、ロックが使用可能かどうかを繰り返し確認しながら、単純にループ(「スピン」)で待機させるロックです。

これはひどく似ています:

while(!ready);

可能な限りポーリングを避けるように教えられましたが、それは完全に準最適なものだったからです。それで、スピンロックは悪い古いポーリングの派手な名前ですか?スピンロックはポーリングとどう違うのですか?

回答:


85

ポーリングとは、リソースあらゆる種類のリソース)の準備ができているかどうかを繰り返し確認することです

スピンロックは、ポーリングしているリソースがロックの場合です。

ポーリングは悪くないことに注意してください。特に、ポーリングの準備ができているデータが通常ある場合、ポーリングは効率的です。ポーリングは、データを取得せずに行う場合にのみ非効率的です。

一方、中断が頻繁に発生するほど大量のデータがある場合、割り込みは非効率的です。中断する前に実際にいくつかの有用な作業を完了することができるほどデータがまれにしか到着しない場合は、効率的です。

15年前、新しい電子メールが届くたびに私を中断するように電子メールプログラムを設定しました。これは週に1、2回発生しました。受信トレイを常にチェックすることは、膨大な時間の無駄でした。

最近では、すべての通知がオフになっています。私自分の受信トレイを見るたびにそこに新しいメールがあることを知っています。ポーリングがより効率的になりました。

スピンロックは、ロックが取られるように)可能性が低い場合に有効である、およびb)場合、ロックが取得され、それは短時間だけ保持されます。つまり、ほとんど競合しないきめの細かいロックには効率的ですが、非常に競合するきめの細かいロックには非効率的です。

(そしてもちろん、スピンロックは真の並列処理がある場合にのみ機能します。そうでない場合、他のスレッドはロックを解除する機会がありません。それは明らかなことですが、とにかく述べたいと思います。)


5
スピンロックは、協調的マルチタスク環境で完全に賢明です。ループ内で制御権を得ていることを確認する必要があります。
ケビン

4
電子メールの素晴らしい例。思い出させるあなたは常に電子メールを持っている ...
ペトルスキー-パドラック

2
@Kevin:スピンロック、つまり空のループでスピンするだけのロックという非常に純粋なアイデアを持っています。(atomically_do { while (lock.is_locked?); lock.acquire! })生成される場合、それは空のループではなく、したがってその純粋主義的な見方ではスピンロックではありません:-Dしかし、もちろん、プラトニックな理想への他のタイプのロックまたはリラクゼーション/追加とのハイブリッド化は、現実の世界で完全に理にかなっています。
ヨルグWミットタグ

3
@bubakazouba:スピンロックは、空のループで文字通り「回転」し、「ロックはまだリリースされていますか?ロックはまだリリースされていますか?ロックはまだリリースされていますか?ロックはまだリリースされていますか?ロックはまだリリースされていますか?」何回も。並列性がない場合、ロックを解除できるスレッドが同時に実行されていないため、事実上無限ループが発生します!あなたのコメントのすぐ上にあるコメントを参照してください。
ヨルグWミットタグ

1
@kasperd:nginxのようなイベント駆動型サーバーソフトウェアでは、引き続き協調的なマルチタスクを見ることができます。その場合、1つのスレッドがあり、ロックはありません。つまり、1つのコアしか利用できません。私の知る限り、真のマルチコア協調マルチタスクの実例は文字通りありません。このようなシステムは、ロックなしの利点なしに協調マルチタスクの欠点をすべて得るため、愚かです。
ケビン

10

スピンロックは、具体的には、達成つのロックのタイプである介してポーリングします。

ポーリングは、何かのステータスを確認する方法です(ステータスが通知されるのを待つのではなく、ステータスを要求することにより)。

キーボードキーのステータスのポーリングなど、すべてのポーリングがスピンロックであるとは限りません。


また、ポーリングは本質的に悪いことではありません。ポーリングの期間が非常に短いと、割り込みの使用に必要な高価なコンテキストシフトを回避できます。もちろん、特に低レベルでは、ポーリングの実装が簡単で、メンテナンスが容易になることもあります。いつものように、絶対値はひどいものなので、オプションを盲目的に使用したり破棄したりするのではなく、ニーズに合わせ適切なパフォーマンス/複雑さのトレードオフを与える方法を使用する必要があります。


5

スピンロックはポーリングとは異なり、数ミリ秒以下の非常に短い時間しか発生しません。ポーリングは無期限に継続できます。

並列プログラミングでは、コンテキストの切り替えやカーネルの移行のコストを回避できるため、ブロッキングよりもスピンの短いエピソードの方が望ましい場合がよくあります。


C#でのSpinLockとSpinWaitの詳細な読み方Cでの
Spinlockと読み書きロック


マイクロ秒を言うつもりだったと思う。1ミリ秒続くロックの場合は、競合時にカーネル呼び出しを行うロック実装を使用する必要があります。
ピーター

@Peterおそらく、それがアルバハリの意味だったのでしょう。それは彼のテキストが言うことです。
ロバートハーヴェイ

4

違いは、スピンロックは(できれば)適切な状況でのみ使用され、これらの状況では非常に効率的であるということです。

リソースが非常に短い時間しかロックされないと予想される場合、たとえばロックが変数の更新のみに使用される場合、スピンロックを使用します。スピンロックは最大速度でロックをポーリングしますが、マイクロ秒未満であることが望ましいです。通常のミューテックスはOS呼び出しで必要になります。IFロックが唯一の時間のわずかな量のために保持されているOSの呼び出しは時間がかかりますが、その後、スピンロックは、CPU時間のわずかな量を使用しています。しかし、この期待が間違っている場合、スピンロックは非常に非効率的です-1つのCPUで100%のCPU時間を使用しますが、通常のミューテックスはOSに入って戻るための時間しかかかりません。

両方が組み合わされることもあります。スピンロックを短時間実行し、スピンロックが機能しない場合は別の戦略に切り替えます。


2

過剰なポーリングは、システムリソースを浪費するため、実行すべきではありません。ということになる、それがシステムリソースを無駄にしない場合は、ポーリングで結構です

たとえば、実際の作業で2%の負荷しか発生しない場合、過度のポーリングによりCPU負荷が100%になります。

ポーリングは以外の目的にも使用できますwhile(!ready)。たとえば、ユーザーがキーを押したかどうかを定期的にチェックすることを意味します。正常な実装では、最大で15ミリ秒に1回チェックされるため、〜2000万クロックサイクルごとに1回チェックされます。この種のポーリングは、システムリソースを無駄にしないため素晴らしいです。

SpinLockは特別な場合ではありません。SpinLockがあり、1つのスレッドがロックに入り、別のスレッドが待機する必要がある場合、待機中のスレッドがシステムリソースを浪費する場合にのみ、SpinLockが間違った選択になります。待機スレッドは、ロックを取得する前にかなりの時間待機する必要がある場合にのみ、システムリソースを浪費します。

したがって、SpinLockを使用して、ロックを解除する前に数千クロックサイクル以上を必要とするもの(たとえば、JavaScriptをオンザフライでコンパイルして実行する)を保護することは、まさにあなたが述べた理由からです。ただし、適切に実装されたハッシュマップにアクセスするなど、SpinLockを使用して迅速に完了するものを保護すると、待機中のスレッドが2〜3回しかスピンせず、システムリソースを浪費しないためです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.