Was genau sind „Spin-Locks“?


108

Ich habe mich immer gefragt, was sie sind: Jedes Mal, wenn ich von ihnen höre, tanzen Bilder von futuristischen schwungradähnlichen Geräten durch meinen Kopf ...

Was sind Sie?

Antworten:


125

Wenn Sie reguläre Sperren (Mutexe, kritische Abschnitte usw.) verwenden, versetzt das Betriebssystem Ihren Thread in den Status WAIT und verhindert dies, indem andere Threads auf demselben Kern geplant werden. Dies hat eine Leistungsbeeinträchtigung zur Folge, wenn die Wartezeit sehr kurz ist, da Ihr Thread jetzt auf eine Vorauszahlung warten muss, um die CPU-Zeit erneut zu erhalten.

Außerdem sind Kernelobjekte nicht in jedem Status des Kernels verfügbar, z. B. in einem Interrupt-Handler oder wenn Paging nicht verfügbar ist usw.

Spinlocks verursachen keine Preemption, sondern warten in einer Schleife ("Spin"), bis der andere Kern die Sperre aufhebt. Dies verhindert, dass der Thread sein Quantum verliert und fortgesetzt wird, sobald die Sperre aufgehoben wird. Der einfache Mechanismus von Spinlocks ermöglicht es einem Kernel, ihn in nahezu jedem Zustand zu verwenden.

Aus diesem Grund ist ein Spinlock auf einem Single-Core-Computer einfach ein "Disrupt Interrupts" oder "Raise IRQL", wodurch die Thread-Planung vollständig verhindert wird.

Spinlocks ermöglichen es Kerneln letztendlich, "Big Kernel Lock" (eine Sperre, die beim Eintritt des Kerns in den Kernel und beim Auslösen am Ausgang erhalten wird) zu vermeiden und die Kernel-Grundelemente granular zu sperren, was zu einer besseren Mehrfachverarbeitung auf Mehrkernmaschinen und damit zu einer besseren Leistung führt.

EDIT : Es stellte sich die Frage: "Heißt das, ich sollte Spinlocks verwenden, wo immer dies möglich ist?" und ich werde versuchen, es zu beantworten:

Wie bereits erwähnt, sind Spinlocks nur an Orten nützlich, an denen die erwartete Wartezeit kürzer als ein Quantum ist (sprich: Millisekunden) und die Vorauszahlung wenig sinnvoll ist (z. B. sind Kernelobjekte nicht verfügbar).

Wenn die Wartezeit unbekannt ist oder wenn Sie sich im Benutzermodus befinden, sind Spinlocks nicht effizient. Sie verbrauchen 100% CPU-Zeit auf dem wartenden Kern, während Sie prüfen, ob ein Spinlock verfügbar ist. Sie verhindern, dass andere Threads auf diesem Kern ausgeführt werden, bis Ihr Quantum abläuft. Dieses Szenario ist nur für kurze Bursts auf Kernel-Ebene möglich und für eine Anwendung im Benutzermodus unwahrscheinlich.

Hier ist eine Frage zu SO, die sich damit befasst: Spinlocks, wie nützlich sind sie?


Bedeutet das, dass ich, wo immer möglich, Spin-Locks (anstelle von Mutex, kritischem Abschnitt usw.) verwenden sollte?

1
Bitte korrigiert mich jemand, wenn ich falsch liege, aber ein Spinlock deaktiviert die Vorauszahlung nicht (dh die Neuplanung). aus dem einfachen Grund, dass, wenn der Spinlock auf eine Ressource wartet, die von einem anderen Prozess gesperrt wurde, diesem zweiten Prozess die Möglichkeit gegeben werden muss, die Ressource auszuführen und freizugeben. oder um den zweiten Prozess auszuführen, muss der erste (sich drehende) Prozess vorweggenommen werden.
user1284631

Stattdessen ändert Spinlock den Prozessstatus nicht von TASK_RUNNING in TASK_INTERRUPTIBLE (ein Ruhezustand) und speichert daher nicht alles über diesen Prozess (Speicher, Cache usw.). Stattdessen wird der Drehvorgang verhindert, aber die "sofort planbaren" Prozesse werden nie beendet: Er wird gespeichert und die anderen Prozesse werden regelmäßig ausgeführt, bis einer von ihnen die Ressource freigibt, auf die der Spinner wartet: zu diesem Zeitpunkt die Spinlock kehrt einfach zurück und der Spinnvorgang kann fortgesetzt werden. Es wartet immer im Status TASK_RUNNING.
user1284631

1
Sie haben Recht damit (siehe auch dies: linuxjournal.com/article/5833 ), aber Tatsache ist, dass das Sperren einer Ressource und das Deaktivieren von Interrupts, obwohl sie nützlich sind, um gemeinsam ausgeführt zu werden, ansonsten nicht verwandte Konzepte sind. Grundsätzlich möchten Sie sicherstellen, dass Sie keine Ressource verwenden, die sich in einem inkonsistenten Zustand befindet. Aus diesem Grund testen Sie deren Sperre. Durch das Deaktivieren von Interrupts (auch Preemption) wird sichergestellt, dass niemand mit Ihrer Wiederbelebung in Konflikt gerät, während Sie sich damit befassen. Dafür müssen Sie jedoch sicherstellen, dass die Ressource beim Erwerb kostenlos ist.
user1284631

1
(Deaktivieren Sie dann die Interrupts, um sicherzugehen, dass keine andere Aufgabe Sie behindert und mit der Ressource herumspielt.) Bei UP (Uniprozessor) ist dies immer der Fall: Der allererste (und die nachfolgenden) Spinlock wird einfach gewährt, Interrupts (dh Preemption) werden deaktiviert und die Aufgabe, die die Ressource verwendet, wird niemals vorbelegt: Sie erledigt alles Job mit der Ressource, dann aktivieren Sie Interrupts (und damit Preemption). Wenn die Vorauszahlung aktiviert ist, ist die Ressource bereits frei. Grundsätzlich gibt es bei UP keine Spinlock-Auseinandersetzung und kein Warten . auf SMP könnte es sein.
user1284631

25

Angenommen, eine Ressource ist durch eine Sperre geschützt. Ein Thread, der Zugriff auf die Ressource wünscht, muss zuerst die Sperre erwerben. Wenn die Sperre nicht verfügbar ist, überprüft der Thread möglicherweise wiederholt, ob die Sperre freigegeben wurde. Während dieser Zeit wartet der besetzte Thread, sucht nach der Sperre, verwendet die CPU, erledigt aber keine nützliche Arbeit. Eine solche Sperre wird als Spin-Sperre bezeichnet.


2
Gute Antwort! +1
Jayesh Bhoi

18

Es ist eine Schleife, die so lange weitergeht, bis eine bestimmte Bedingung erfüllt ist:

while(cantGoOn) {};

1
Und / oder während (cantGoOn) {sleep (0)};
Jiminion

@Jiminion, wenn Sie ein setzen sleep(0), würde es den Thread verhindern und den Zweck der Verwendung eines Spinlocks in erster Linie zunichte machen . Wenn Sie anderen Threads nachgeben müssen, sollten Sie eine reguläre Sperre verwenden. (Ich weiß, dass Ihr Kommentar sehr alt ist, wollte aber verhindern, dass andere dies als Vorschlag sehen).
Sedat Kapanoglu

"Der Wert Null bewirkt, dass der Thread den Rest seiner Zeitscheibe an einen anderen Thread weitergibt, der zur Ausführung bereit ist. Wenn keine anderen Threads zur Ausführung bereit sind, kehrt die Funktion sofort zurück und der Thread setzt die Ausführung fort."
Jiminion



3

SpinLocks sind diejenigen, in denen der Thread wartet, bis die Sperre verfügbar ist. Dies wird normalerweise verwendet, um den Aufwand für das Abrufen der Kernelobjekte zu vermeiden, wenn das Kernelobjekt innerhalb eines kurzen Zeitraums erfasst werden kann.

Ex:

While(SpinCount-- && Kernel Object is not free)
{}

try acquiring Kernel object

3

Sie möchten einen Spinlock verwenden, wenn Sie der Meinung sind, dass es billiger ist, in eine belebte Warteschleife einzutreten und eine Ressource zu bündeln, anstatt sie zu blockieren, wenn die Ressource gesperrt ist.

Das Drehen kann vorteilhaft sein, wenn Sperren feinkörnig und zahlreich sind (z. B. eine Sperre pro Knoten in einer verknüpften Liste) sowie wenn die Haltezeiten für Sperren immer extrem kurz sind. Im Allgemeinen sollte man beim Halten einer Spin-Sperre vermeiden, zu blockieren, alles aufzurufen, was selbst blockieren könnte, mehr als eine Spin-Sperre gleichzeitig zu halten, dynamisch verteilte Anrufe (Schnittstelle und Virtuals) zu tätigen und statisch verteilte Anrufe in einen Code zu tätigen, den man nicht tut. ' t besitzen oder Speicher zuweisen.

Es ist auch wichtig zu beachten, dass SpinLock aus Leistungsgründen ein Werttyp ist. Daher muss man sehr vorsichtig sein, um eine SpinLock-Instanz nicht versehentlich zu kopieren, da die beiden Instanzen (das Original und die Kopie) dann völlig unabhängig voneinander wären, was wahrscheinlich zu einem fehlerhaften Verhalten der Anwendung führen würde. Wenn eine SpinLock-Instanz weitergegeben werden muss, sollte sie als Referenz und nicht als Wert übergeben werden.


1

Kurz gesagt, Spinlock verwendet Atomic Compare and Swap (CAS) oder Test-and-Set-ähnliche Anweisungen, um eine sperrenfreie, wartefreie, thread-sichere Sprache zu implementieren. Solche Strukturen lassen sich in Mehrkernmaschinen gut skalieren.


Per Definition wird ein Spinlock nicht verwendet, um etwas zu implementieren, das frei von Sperren ist oder frei wartet.
Rdb

0

Es ist eine Schleife, die sich dreht, bis eine Bedingung erfüllt ist.


0

Ja, der Punkt bei Spin-Locks (im Vergleich zu herkömmlichen kritischen Abschnitten usw.) ist, dass sie unter bestimmten Umständen eine bessere Leistung bieten (Multicore-Systeme ..), da sie nicht sofort den Rest des Thread-Quantums liefern.


0

Spinlock ist eine Art Schloss, das nicht blockierbar und nicht schlaffähig ist. Jeder Thread, der einen Spinlock für eine gemeinsam genutzte oder kritische Ressource erwerben möchte, dreht sich kontinuierlich und verschwendet den CPU-Verarbeitungszyklus, bis er die Sperre für die angegebene Ressource erhält. Sobald Spinlock erworben wurde, versucht es, die Arbeit in seinem Quantum abzuschließen und dann die Ressource freizugeben. Spinlock ist die Art von Sperre mit der höchsten Priorität. Man kann einfach sagen, dass es sich um eine nicht präventive Art von Sperre handelt.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.