Чем спинлок отличается от опроса?

41

Спинлок и опрос - это одно и то же?

Википедия:

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

Это звучит очень похоже на:

while(!ready);

Меня учили избегать опросов, когда это было возможно, так как это было неоптимально. Так что же, спинлок - модное название для плохого старого опроса? Чем спинлок отличается от опроса?

Лорд лох
источник

Ответы:

85

Опрос - это многократная проверка того, готов ли ресурс ( любой вид ресурса).

Спинлок - это когда блокируемый ресурс опрашивается.

Обратите внимание, что опрос не плохо. В частности, опрос эффективен, когда при опросе обычно имеются данные. Опрос только неэффективен, если вы делаете это без получения каких-либо данных взамен.

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

Я могу привести вам реальный пример из собственного опыта: 15 лет назад у меня была настроена программа электронной почты, чтобы прерывать меня каждый раз, когда приходит новое электронное письмо. Это происходило один или два раза в неделю. Постоянная проверка моего почтового ящика была бы колоссальной тратой времени.

В настоящее время у меня все уведомления отключены. Я знаю, что всякий раз, когда я заглядываю в свой почтовый ящик, там появляются новые письма. Опрос намного эффективнее сейчас.

Спин-блокировки эффективны, когда а) вероятность того, что блокировка снята, мала, и б) если блокировка снята, она будет удерживаться только в течение короткого времени. Другими словами: он эффективен для в большинстве случаев неконтролируемых мелкозернистых замков, но неэффективен для сильно конфликтующих крупнозернистых замков.

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

Йорг Миттаг
источник
5
Спинлоки могут быть совершенно разумными в совместной многозадачной среде. Вы просто должны убедиться, что вы даете контроль в цикле.
Кевин
4
Отличный пример с электронными письмами. Напоминает мне о вас всегда есть электронная почта ...
Петр Пудлак
2
@Kevin: У меня очень пуристическая идея спин-блокировки, буквально блокировки, которая просто вращается в пустом цикле. ( atomically_do { while (lock.is_locked?); lock.acquire! }) Если он уступает, это не пустой цикл и, следовательно, не спин-блокировка в этом пуристическом представлении :-D Но, конечно, некоторая гибридизация с другими типами замков или ослаблений / дополнений к платоническому идеалу имеет смысл в реальном мире.
Йорг Миттаг
3
@bubakazouba: спин-блокировка работает, буквально "вращаясь" в пустом цикле и проверяя: "Блокировка еще снята? Блокировка снята еще? Блокировка снята еще? Блокировка снята еще? Блокировка снята еще?" снова и снова. Если параллелизма нет, тогда не будет запущен другой поток, который мог бы снять блокировку, поэтому у вас фактически есть бесконечный цикл! Смотрите комментарий прямо над вашим.
Йорг Миттаг
1
@kasperd: Вы все еще можете видеть совместную многозадачность в управляемом событиями серверном программном обеспечении, таком как nginx. В этом случае есть один поток и нет блокировки, что означает, что вы можете использовать только одно ядро. Насколько я знаю, в реальном мире практически нет примеров настоящей многоядерной совместной многозадачности. Такая система была бы глупой, так как вы могли бы получить все недостатки совместной многозадачности без преимуществ без блокировок.
Кевин
10

Спинлок - это тип блокировки, в частности, такой, который достигается с помощью опроса.

Опрос - это метод проверки статуса чего-либо (путем запроса статуса, в отличие от ожидания получения статуса).

Не весь опрос является спин-блокировкой, например, опрос статуса клавиш клавиатуры.


Кроме того, опрос не является плохим. Очень короткие периоды опроса могут избежать дорогостоящих сдвигов контекста, которые потребуются для использования прерываний, не говоря уже о том, что опрос может иногда быть проще в реализации и, следовательно, проще в обслуживании, особенно на более низких уровнях. Как обычно, абсолюты страшная вещь, и вы должны использовать метод , который дает соответствующие показатели эффективности торговли / сложности от ваших потребностей , как вы измерили их , а не слепо использовать или отбрасывание вариантов.

8bittree
источник
5

Спинлок отличается от опроса тем, что он происходит только в течение очень короткого периода времени, порядка нескольких миллисекунд или менее. Опрос может продолжаться бесконечно.

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

Дальнейшее чтение
SpinLock и SpinWait в C # Spinlocks и
блокировки чтения-записи в C

Роберт Харви
источник
Я думаю, что вы хотели сказать, микросекунды. Для блокировки, которая длится целую миллисекунду, мы должны использовать реализацию блокировки, которая вызывает ядро ​​в случае конфликта.
Питер
@ Питер Возможно, именно это имел в виду Албахари. Это то, что говорит его текст.
Роберт Харви
4

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

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

Иногда оба сочетаются; Вы запускаете спин-блокировку в течение короткого времени и переключаетесь на другую стратегию, если спин-блокировка не работает.

gnasher729
источник
2

Чрезмерный опрос это то, что вы не должны делать, потому что это тратит впустую системные ресурсы. Из этого следует, что опрос хорош, если он не тратит системные ресурсы .

Например, чрезмерный опрос приведет к загрузке процессора до 100% в тех случаях, когда фактическая работа приведет только к загрузке 2%.

Опрос может быть использован для других вещей, чем while(!ready). Например, это означает регулярную проверку, нажал ли пользователь клавишу. Разумная реализация будет проверять самое большее один раз каждые 15 миллисекунд, так что это одна проверка каждые ~ 20 миллионов тактов. Такой опрос великолепен, потому что он не тратит ресурсы системы.

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

Поэтому использование SpinLock для защиты всего, что требует нескольких тысяч тактов или более, прежде чем он снова разблокируется (например, компиляция и выполнение фрагмента javascript на лету), плохо, именно по той причине, которую вы указали. Но использование SpinLock для защиты чего-то, что быстро завершается, например, доступ к правильно реализованной хэш-карте - это хорошо, потому что ожидающий поток будет вращаться только 2 или 3 раза и, следовательно, не тратит системные ресурсы.

Питер
источник