Czym dokładnie są „zamki spinowe”?


108

Zawsze się zastanawiałem, czym one są: za każdym razem, gdy o nich słyszę, tańczą (toczą się?) W mojej głowie obrazy futurystycznych urządzeń przypominających koło zamachowe ...

Czym oni są?

Odpowiedzi:


125

Kiedy używasz zwykłych blokad (muteksy, sekcje krytyczne itp.), System operacyjny ustawia twój wątek w stan OCZEKIWANIA i wywłaszcza go, planując inne wątki w tym samym rdzeniu. Ma to spadek wydajności, jeśli czas oczekiwania jest naprawdę krótki, ponieważ twój wątek musi teraz czekać na wywłaszczanie, aby ponownie otrzymać czas procesora.

Poza tym obiekty jądra nie są dostępne w każdym stanie jądra, na przykład w obsłudze przerwań lub gdy stronicowanie nie jest dostępne itp.

Spinlocki nie powodują wywłaszczania, ale czekają w pętli („spin”), aż drugi rdzeń zwolni blokadę. Zapobiega to utracie kwantu wątku i kontynuowaniu działania, gdy tylko blokada zostanie zwolniona. Prosty mechanizm spinlocków pozwala jądru wykorzystać go w prawie każdym stanie.

Dlatego na komputerze z jednym rdzeniem blokada spinlock jest po prostu „wyłączaniem przerwań” lub „podnoszeniem IRQL”, co całkowicie uniemożliwia planowanie wątków.

Spinlocky ostatecznie pozwalają jądrom uniknąć "Big Kernel Lock" (blokada uzyskiwana, gdy rdzeń wchodzi do jądra i zwalniana przy wyjściu) i mają granularne blokowanie nad prymitywami jądra, powodując lepsze przetwarzanie wielordzeniowe na maszynach wielordzeniowych, a tym samym lepszą wydajność.

EDYCJA : Pojawiło się pytanie: „Czy to oznacza, że ​​powinienem używać spinlocków wszędzie tam, gdzie to możliwe?” i spróbuję odpowiedzieć:

Jak wspomniałem, spinlocki są przydatne tylko w miejscach, w których przewidywany czas oczekiwania jest krótszy niż kwant (czytaj: milisekundy), a wywłaszczanie nie ma większego sensu (np. Obiekty jądra nie są dostępne).

Jeśli czas oczekiwania jest nieznany lub jeśli jesteś w trybie użytkownika, Spinlocki nie są wydajne. Zużywasz 100% czasu procesora na oczekującym rdzeniu podczas sprawdzania, czy blokada jest dostępna. Zapobiegasz uruchamianiu innych wątków na tym rdzeniu, dopóki kwant nie wygaśnie. Ten scenariusz jest możliwy tylko w przypadku krótkich serii na poziomie jądra i mało prawdopodobna opcja dla aplikacji w trybie użytkownika.

Oto pytanie dotyczące SO, które dotyczy tego: Spinlocks, jak przydatne są?


czy to znaczy, że powinienem blokować spin (zamiast muteksu, sekcji krytycznej itp.), gdziekolwiek jest to możliwe?

1
niech ktoś mnie poprawi, jeśli się mylę, ale spinlock nie wyłącza wywłaszczania (tj. ponownego planowania). z prostego powodu, że jeśli spinlock oczekuje na zasób zablokowany przez inny proces, to ten drugi proces musi mieć szansę na uruchomienie i zwolnienie zasobu. lub uruchomienie drugiego procesu wymaga wywłaszczenia pierwszego (wirującego) procesu.
user1284631

zamiast tego spinlock robi to, że nie zmienia stanu procesu z TASK_RUNNING na TASK_INTERRUPTIBLE (który jest stanem uśpienia), a zatem nie zapisuje wszystkiego o tym procesie (pamięć, pamięć podręczna i tak dalej). zamiast tego proces przędzenia jest wywłaszczany, ale nigdy nie opuszcza procesów, które można od razu zaplanować: jest przechowywany w pamięci, a inne procesy są regularnie uruchamiane, dopóki jeden z nich nie zwolni zasobu, na który czeka spinner: w tym czasie spinlock po prostu wraca i proces wirowania może być kontynuowany. czeka w stanie zawsze TASK_RUNNING.
user1284631

1
masz rację (zobacz również to: linuxjournal.com/article/5833 ), ale faktem jest, że blokowanie zasobu i wyłączanie przerwań, chociaż przydatne do wykonania łącznie, są poza tym pojęciami niezwiązanymi. w zasadzie chcesz mieć pewność, że nie używasz zasobu znalezionego w niespójnym stanie i dlatego testujesz jego blokadę. wyłączanie przerwań (również wywłaszczania) zapewnia, że ​​tak, nikt nie będzie bałaganu z twoim wskrzeszeniem, kiedy będziesz sobie z nim radzić. ale w tym celu musisz mieć pewność, że zasób jest bezpłatny, gdy go kupujesz.
user1284631

1
(następnie wyłącz przerwania, aby mieć pewność, że żadne inne zadanie Cię nie wyprzedza i nie miesza z zasobem). na UP (uni-procesor), zawsze tak jest: pierwszy (i kolejne) spinlock jest po prostu przyznawany, przerwania (tj. wywłaszczanie) są wyłączone, a zadanie korzystające z zasobu nigdy nie jest wywłaszczane: robi wszystko, co w jego mocy zadanie z zasobem, następnie włącz przerwania (a tym samym wywłaszczanie). gdy jest włączone wywłaszczanie, zasób jest już wolny. w zasadzie na UP nie ma rywalizacji o spinlock i nie ma czekania . na SMP może to być.
user1284631

25

Powiedzmy, że zasób jest chroniony przez blokadę, a wątek, który chce uzyskać dostęp do zasobu, musi najpierw uzyskać blokadę. Jeśli blokada nie jest dostępna, wątek może wielokrotnie sprawdzać, czy blokada została zwolniona. W tym czasie zajęty wątek czeka, sprawdzając blokadę, używając procesora, ale nie wykonując żadnej użytecznej pracy. Taka blokada jest określana jako blokada spinowa.


2
Niezła odpowiedź! +1
Jayesh Bhoi,

18

Jest to istotna pętla, która trwa, dopóki nie zostanie spełniony określony warunek:

while(cantGoOn) {};

1
I / lub while (cantGoOn) {sleep (0)};
Jiminion

@Jiminion, jeśli umieścisz a sleep(0), spowoduje to wywłaszczenie wątku, zabijając cel używania spinlocka w pierwszej kolejności. jeśli chcesz poddać się innym wątkom, powinieneś używać zwykłej blokady. (Wiem, że twój komentarz jest bardzo stary, ale chciałem, aby inni nie postrzegali go jako sugestii).
Sedat Kapanoglu

„Wartość zero powoduje, że wątek porzuca pozostałą część swojego przedziału czasu do dowolnego innego wątku, który jest gotowy do uruchomienia. Jeśli nie ma innych wątków gotowych do uruchomienia, funkcja natychmiast wraca, a wątek kontynuuje wykonywanie”.
Jiminion


5

To rodzaj zamka, który jest zajęty czekaniem

Jest to uważane za anty-wzorzec, z wyjątkiem programowania sterowników bardzo niskiego poziomu (gdzie może się zdarzyć, że wywołanie „właściwej” funkcji oczekiwania wiąże się z większym narzutem niż zwykłe blokowanie na kilka cykli).

Zobacz na przykład Spinlocks w jądrze Linuksa .


3

SpinLocks to te, w których wątek czeka, aż blokada będzie dostępna. Zwykle jest to używane, aby uniknąć narzutu związanego z pobieraniem obiektów jądra, gdy istnieje zakres uzyskania obiektu jądra w jakimś krótkim okresie czasu.

Dawny:

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

try acquiring Kernel object

3

Chciałbyś użyć spinlocka, gdy uważasz, że tańsze jest wejście do zajętej pętli oczekiwania i połączenie zasobu zamiast blokowania, gdy zasób jest zablokowany.

Obracanie może być korzystne, gdy zamki są drobnoziarniste i duże (na przykład blokada na węzeł w połączonej liście), a także gdy czasy utrzymania blokad są zawsze bardzo krótkie. Generalnie, trzymając blokadę spinu, należy unikać blokowania, wywoływania czegokolwiek, co samo może blokować, trzymania więcej niż jednej blokady spinu naraz, wykonywania wywołań wysyłanych dynamicznie (interfejs i wirtualne), wykonywania wywołań wysyłanych statycznie do dowolnego kodu, którego się nie robi. posiadanie lub przydzielanie pamięci.

Należy również zauważyć, że SpinLock jest typem wartości ze względu na wydajność. W związku z tym należy bardzo uważać, aby przypadkowo nie skopiować instancji SpinLock, ponieważ dwie instancje (oryginał i kopia) byłyby wówczas całkowicie niezależne od siebie, co prawdopodobnie doprowadziłoby do błędnego zachowania aplikacji. Jeśli instancja SpinLock musi być przekazywana, powinna być przekazywana przez odwołanie, a nie przez wartość.


1

W skrócie, spinlock wykorzystuje atomowe porównywanie i zamianę (CAS) lub testowanie i ustawianie, takie jak instrukcje, aby zaimplementować idiom lock free, wait free thread safe. Takie struktury dobrze skalują się w maszynach wielordzeniowych.


Z samej definicji spinlock nie jest używany do implementacji czegokolwiek bez blokady lub czekania.
rdb

0

To pętla, która obraca się, dopóki warunek nie zostanie spełniony.


0

Cóż, tak - celem blokad spinu (w porównaniu z tradycyjnymi krytycznymi sekcjami itp.) Jest to, że oferują one lepszą wydajność w pewnych okolicznościach (systemy wielordzeniowe ...), ponieważ nie dają od razu pozostałej części kwantowej wątku.


0

Spinlock to rodzaj zamka, który nie jest w stanie blokować ani spać. Każdy wątek, który chce uzyskać blokadę spinlock dla dowolnego udostępnionego lub krytycznego zasobu, będzie stale obracał się, marnując cykl przetwarzania procesora, aż uzyska blokadę dla określonego zasobu. Po zdobyciu spinlocka, próbuje zakończyć pracę w swoim kwantie, a następnie odpowiednio zwolnić zasób. Spinlock jest rodzajem zamka o najwyższym priorytecie, można po prostu powiedzieć, że jest to blokada bez wywłaszczania.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.