Beim Abrufen wird wiederholt geprüft, ob eine Ressource (eine beliebige Ressource) bereit ist.
Ein Spinlock ist, wenn die Ressource, die Sie abfragen, eine Sperre ist.
Beachten Sie, dass das Polling nicht schlecht ist. Das Abrufen ist insbesondere dann effizient, wenn zum Zeitpunkt des Abrufs in der Regel Daten verfügbar sind. Abfragen sind nur dann ineffizient, wenn Sie dies tun, ohne dass Daten zurückgegeben werden.
Interrupts hingegen sind ineffizient, wenn so viele Daten vorhanden sind, dass Sie ständig unterbrochen werden. Sie sind effizient, wenn Daten selten genug eingehen, dass Sie nützliche Arbeiten erledigen können, bevor Sie unterbrochen werden.
Ich kann Ihnen ein reales Beispiel aus eigener Erfahrung geben: Vor 15 Jahren hatte ich mein E-Mail-Programm so eingerichtet, dass es mich jedes Mal unterbrach, wenn eine neue E-Mail einging. Dies geschah ein- oder zweimal pro Woche. Das ständige Überprüfen meines Posteingangs wäre eine gewaltige Zeitverschwendung gewesen.
Heutzutage habe ich alle Benachrichtigungen deaktiviert. Ich weiß, dass es dort immer neue E-Mails geben wird, wenn ich in meinen Posteingang schaue. Polling ist jetzt viel effizienter.
Spinlocks sind effizient, wenn a) die Wahrscheinlichkeit, dass die Sperre ergriffen wird, gering ist, und b) wenn die Sperre ergriffen wird, wird sie nur für eine kurze Zeit gehalten. Mit anderen Worten: Es ist effizient für größtenteils unbearbeitete feinkörnige Schleusen, aber ineffizient für stark umkämpfte grobkörnige Schleusen.
(Und natürlich funktionieren Spinlocks nur, wenn es eine echte Parallelität gibt, sonst hat der andere Thread keine Chance, die Sperre aufzuheben. Ich denke, das liegt auf der Hand, aber ich wollte es trotzdem sagen.)
atomically_do { while (lock.is_locked?); lock.acquire! }
) Wenn es nachgibt, ist es in dieser puristischen Sichtweise keine leere Schleife und somit auch kein Spinlock :-D Aber natürlich ist eine gewisse Hybridisierung mit anderen Arten von Sperren oder Entspannungen / Ergänzungen des platonischen Ideals in der realen Welt durchaus sinnvoll.Ein Spinlock ist eine Art Sperre, die speziell durch Abfragen erreicht wird.
Polling ist eine Methode, um den Status von etwas zu überprüfen (indem Sie nach dem Status fragen, anstatt darauf zu warten, den Status zu erfahren).
Nicht alle Abfragen sind Spinlocks, z. B. das Abfragen des Status von Tastaturtasten.
Polling ist auch nicht von Natur aus schlecht. Sehr kurze Abfrageperioden können teure Kontextverschiebungen vermeiden, die für die Verwendung von Interrupts erforderlich wären. Außerdem kann die Abfrage manchmal einfacher zu implementieren und damit einfacher zu warten sein, insbesondere auf niedrigeren Ebenen. Wie üblich sind Absoluten eine schreckliche Sache, und Sie sollten die Methode verwenden , die die entsprechende Leistung / Komplexität Trade - off für Ihre Bedürfnisse gibt , wie Sie sie gemessen haben , anstatt blind verwenden oder verwerfen Optionen.
quelle
Spinlock unterscheidet sich von Polling, da es nur für einen sehr kurzen Zeitraum in der Größenordnung von wenigen Millisekunden oder weniger auftritt . Die Abstimmung kann auf unbestimmte Zeit fortgesetzt werden.
Bei der parallelen Programmierung ist eine kurze Folge des Spinnens oft der Blockierung vorzuziehen, da die Kosten für Kontextwechsel und Kernelübergänge vermieden werden.
Weiterführende
Literatur SpinLock und SpinWait in C #
Spinlocks und Read-Write-Locks in C
quelle
Der Unterschied besteht darin, dass ein Spinlock (hoffentlich) nur in Situationen verwendet wird, in denen es angemessen ist, und in diesen Situationen ist es sehr effizient.
Sie verwenden ein Spinlock, wenn Sie erwarten, dass eine Ressource nur für eine sehr kurze Zeit gesperrt wird - zum Beispiel, wenn eine Sperre nur zum Aktualisieren einer Variablen verwendet wird. Das Spinlock fragt die Sperre mit maximaler Geschwindigkeit ab, aber hoffentlich für weniger als Mikrosekunden. Ein normaler Mutex würde einen OS-Aufruf erfordern. WENN die Sperre nur für eine winzige Zeitspanne gehalten wird, verbraucht die Spinlock-Funktion nur eine winzige Menge an CPU-Zeit, während der OS-Aufruf länger dauert. Wenn diese Erwartung jedoch falsch ist, ist der Spinlock sehr ineffizient - er beansprucht 100% der CPU-Zeit auf einer CPU, während der normale Mutex nur die Zeit benötigt, um das Betriebssystem aufzurufen und zurückzukehren.
Manchmal werden beide kombiniert; Sie führen die Drehsperre für eine kurze Zeit aus und wechseln zu einer anderen Strategie, wenn die Drehsperre nicht funktioniert.
quelle
Übermäßiges Abfragen ist etwas, das Sie nicht tun sollten, da es Systemressourcen verschwendet. Daraus folgt, dass das Abrufen in Ordnung ist, wenn keine Systemressourcen verschwendet werden .
Beispielsweise wird durch übermäßiges Abfragen die CPU-Auslastung auf 100% erhöht, wenn die tatsächliche Arbeit nur zu einer Auslastung von 2% führen würde.
Polling kann für andere Zwecke als verwendet werden
while(!ready)
. Zum Beispiel bedeutet dies, regelmäßig zu überprüfen, ob der Benutzer eine Taste gedrückt hat. Eine vernünftige Implementierung prüft höchstens einmal alle 15 Millisekunden, es ist also eine Prüfung alle ~ 20 Millionen Taktzyklen. Diese Art der Abfrage ist großartig, da keine Systemressourcen verschwendet werden.Ein SpinLock ist kein Sonderfall. Wenn wir einen SpinLock haben und ein Thread in die Sperre eintritt und ein anderer warten muss, ist der SpinLock genau dann die falsche Wahl, wenn der wartende Thread Systemressourcen verschwendet. Der wartende Thread verschwendet Systemressourcen genau dann, wenn er eine erhebliche Zeitspanne warten muss, bevor er die Sperre erwerben kann.
Daher ist die Verwendung eines SpinLocks zum Schutz von Objekten, die einige tausend oder mehr Taktzyklen benötigen, bevor sie wieder entsperrt werden (z. B. das Kompilieren und Ausführen eines JavaScript-Elements im laufenden Betrieb), genau aus dem von Ihnen angegebenen Grund schlecht. Die Verwendung von SpinLock zum Schutz von Elementen, die schnell ausgeführt werden, wie beispielsweise der Zugriff auf eine ordnungsgemäß implementierte Hash-Map, ist jedoch in Ordnung, da der wartende Thread nur zwei- oder dreimal ausgeführt wird und daher keine Systemressourcen verschwendet.
quelle