Что такое точно “спин-блокировки”?

Я всегда задавался вопросом, каковы они: каждый раз, когда я слышу о них, изображения футуристических подобных маховику устройств идут, танцуя (прокрутка?) через мой ум...

Каковы они?

94
задан Alex B 24 December 2009 в 08:58
поделиться

9 ответов

При использовании обычных блокировок (мьютексов, критических секций и т.д.) операционная система переводит свой поток в состояние WAIT и вытесняет его, планируя другие потоки на том же ядре, и вытесняет его. Это приводит к снижению производительности, если время ожидания действительно короткое, потому что ваш поток теперь вынужден ждать, когда предупреждение снова получит процессорное время.

Кроме того, объекты ядра доступны не во всех состояниях ядра, например, в обработчике прерываний, при недоступности подкачки и т.д.

Спин-блокировки не вызывают преемственности, а ждут в цикле ("spin"), пока другое ядро не освободит блокировку. Это предотвращает потерю потоком своего кванта и продолжается, как только блокировка освобождается. Простой механизм спин-блокировок позволяет ядру использовать его практически в любом состоянии.

Поэтому на одноядерной машине спинлок - это просто "отключить прерывание" или "поднять IRQL", что полностью исключает возможность планирования потока.

Блокировки ядра, в конечном счете, позволяют ядрам избегать "большой блокировки ядра" (блокировки, получаемой при входе ядра в ядро и освобождаемой при выходе) и имеют гранулярную блокировку по примитивам ядра, что приводит к лучшей многопроцессорности на многоядерных машинах и, таким образом, лучшей производительности.

EDIT: Возник вопрос: "Означает ли это, что я должен использовать spinlocks там, где это возможно?", и я попытаюсь ответить на него:

Как я уже упоминал, Spinlocks полезен только в тех местах, где ожидаемое время ожидания меньше кванта (читай: миллисекунды), а преемственность не имеет особого смысла (например, объекты ядра недоступны).

Если время ожидания неизвестно, или если вы находитесь в пользовательском режиме, Spinlocks не эффективны. Вы потребляете 100% процессорного времени на ожидающем ядре во время проверки наличия спинблока. Вы не позволяете другим потокам работать на этом ядре до тех пор, пока ваш квант не истечет. Этот сценарий возможен только при коротких всплестках на уровне ядра и вряд ли является вариантом для пользовательского приложения.

Вот вопрос в SO, адресующийся к этому: Спинблоки, насколько они полезны?

111
ответ дан 24 November 2019 в 06:06
поделиться

Допустим, ресурс защищен блокировкой, поток, который хочет получить доступ к ресурсу, должен сначала получить блокировку. Если блокировка недоступна, поток может многократно проверить, был ли он освобожден. В течение этого времени поток, занятый, ждет, проверяя блокировку, используя процессор, но не выполняя никакой полезной работы. Такая блокировка называется блокировкой вращения.

.
22
ответ дан 24 November 2019 в 06:06
поделиться

SpinLocks - это те, в которых поток ждет, пока не станет доступен замок. Обычно это используется, чтобы избежать накладных расходов на получение объектов ядра, когда есть возможность получить объект ядра за небольшой промежуток времени.

Ex:

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

try acquiring Kernel object
3
ответ дан 24 November 2019 в 06:06
поделиться
 while(something != TRUE ){};
 // it happend
 move_on();
7
ответ дан 24 November 2019 в 06:06
поделиться

Ну, да - суть спиновых замков (по сравнению с традиционными критическими секциями и т.д.) заключается в том, что при некоторых обстоятельствах (многоядерные системы...) они предлагают лучшую производительность, так как не сразу дают остальной квант потока.

0
ответ дан 24 November 2019 в 06:06
поделиться

Это цикл, который вращается до тех пор, пока не будет выполнено условие

.
0
ответ дан 24 November 2019 в 06:06
поделиться

В двух словах spinLock использует атомные сравнения и подкачки (CAS) или инструкции типа "тест и набор" для реализации безопасной идиомы "свободный поток ждет свободного". Такие структуры хорошо масштабируются в многоядерных машинах.

1
ответ дан 24 November 2019 в 06:06
поделиться

Это пертентный цикл, который продолжается до выполнения определенного условия:

while(cantGoOn) {};
17
ответ дан 24 November 2019 в 06:06
поделиться

Это тип блокировки, который делает оживленным ждать

. Это считается анти-образцом, за исключением очень низкоуровневого программирования драйверов (где он может произойти, что вызывание «правильной» функции ожидания имеет больше накладных, чем Просто занят блокировкой для нескольких циклов).

См. Например Спинлокна в ядре Linux .

5
ответ дан 24 November 2019 в 06:06
поделиться