Что такое "спин-лок"? - PullRequest
       59

Что такое "спин-лок"?

89 голосов
/ 24 декабря 2009

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

Что это?

Ответы [ 11 ]

106 голосов
/ 24 декабря 2009

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

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

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

Вот почему на одноядерном компьютере спин-блокировка - это просто «отключение прерываний» или «повышение IRQL», которое полностью предотвращает планирование потоков.

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

РЕДАКТИРОВАТЬ: возник вопрос: "Значит ли это, что я должен использовать спин-блокировки везде, где это возможно?" и я постараюсь ответить на него:

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

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

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

19 голосов
/ 24 декабря 2009

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

17 голосов
/ 24 декабря 2009

Очень много циклов, которые продолжаются, пока не будет выполнено определенное условие:

while(cantGoOn) {};
7 голосов
/ 24 декабря 2009
 while(something != TRUE ){};
 // it happend
 move_on();
5 голосов
/ 24 декабря 2009

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

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

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

3 голосов
/ 12 ноября 2015

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

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

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

3 голосов
/ 24 декабря 2009

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

Ex:

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

try acquiring Kernel object
1 голос
/ 24 декабря 2009

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

0 голосов
/ 29 мая 2017

Spinlock, это тип блокировки, который не блокируется и не спит. Любой поток, который хочет получить спин-блокировку для любого общего или критического ресурса, будет постоянно вращаться, тратя впустую цикл обработки ЦП, пока не получит блокировку для указанного ресурса. Получив спин-блокировку, он пытается завершить работу в своем кванте, а затем высвободить ресурс соответственно. Спинлок - это блокировка с наивысшим приоритетом, просто можно сказать, что это не приоритетный тип блокировки.

0 голосов
/ 24 декабря 2009

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

...