Чим спінлок відрізняється від опитування?


41

Чи одне й те саме:

Вікіпедія:

спінлок - це замок, який призводить до того, що потік намагається придбати його просто зачекати в циклі ("віджимання"), повторно перевіряючи, чи блокування доступне

Це звучить жахливо так:

while(!ready);

Мене навчали уникати опитування, коли це було можливо, оскільки це було недостатньо оптимальним. Отже, чи є спінлок фантастичним назвою для поганих старих опитувань? Чим спіклок відрізняється від опитування?

Відповіді:


85

Опитування стосується неодноразової перевірки готовності ресурсу ( будь-якого виду).

Спінінг - це коли блокування ресурсу, який ви опитуєте.

Зауважте, що опитування не є поганим. Зокрема, опитування ефективне, коли зазвичай є дані, готові до опитування. Опитування є неефективним лише в тому випадку, якщо ви робите це, не отримуючи жодних даних взамін.

З іншого боку, переривання неефективні, якщо є стільки даних, що ви постійно перериваєтесь. Вони ефективні, якщо дані надходять досить рідко, що ви можете фактично виконати якусь корисну роботу, перш ніж перерватися.

Я можу навести приклад із реального життя з власного досвіду: 15 років тому в мене була створена програма електронної пошти, щоб перервати мене щоразу, коли надходить нова електронна пошта. Що траплялося один-два рази на тиждень. Постійно перевіряти папку "Вхідні" було б колосальною тратою часу.

На сьогоднішній день у мене всі повідомлення вимкнено. Я знаю, що кожного разу, коли я заглянув у свою поштову скриньку, там з’являться нові електронні листи. Зараз опитування значно ефективніше.

Спінлок є ефективним, коли: а) ймовірність того, що замок буде знято, і б) якщо замок знятий, він буде триматися лише ненадовго. Іншими словами: він ефективний для переважно непомітних дрібнозернистих замків, але неефективний для сильно замкнутих грубозернистих замків.

(І, звичайно, спінкі працюють лише тоді, коли існує справжній паралелізм, інакше інший потік не матиме шансу звільнити замок. Я думаю, це очевидно, але я хотів це заявити все-таки.)


5
Спінлок може бути ідеально чутливим у кооперативному багатозадачному середовищі. Вам просто потрібно переконатися, що ви поступаєтеся керуванням у циклі.
Кевін

4
Чудовий приклад з електронними листами. Нагадує, що у вас завжди є електронна пошта ...
Петро Пудлак

2
@Kevin: У мене дуже пуристичне уявлення про спінок, буквально про замок, який просто крутиться в порожній петлі. ( atomically_do { while (lock.is_locked?); lock.acquire! }) Якщо вона поступається, це не порожній цикл і, отже, не прядок у цьому пуристичному погляді :-D Але, звичайно, деяка гібридизація з іншими типами замків або релаксацій / доповнень до платонічного ідеалу мають ідеальний сенс у реальному світі.
Йорг W Міттаг

3
@bubakazouba: Спінінг працює, буквально "обертаючись" у порожній цикл і перевіряючи "Чи заблоковано замок ще? Чи заблоковано замок ще? Чи замок ще випущений? Замок ще випущений? Замок ще вийшов?" знову і знову. Якщо немає паралелізму, не існує одночасно іншого потоку, який міг би звільнити замок, тому ви фактично маєте нескінченний цикл! Дивіться коментар безпосередньо над вашим.
Йорг W Міттаг

1
@kasperd: Ви все ще можете бачити спільну багатозадачність у керованому подіями серверному програмному забезпеченні, наприклад, nginx. У цьому випадку є одна нитка і немає блокування, а це означає, що ви можете використовувати лише одне ядро. Наскільки мені відомо, буквально немає прикладів справжнього багатоядерного кооперативного багатозадачності. Така система була б дурною, оскільки ви отримаєте всі недоліки кооперативної багатозадачності, не маючи жодних замків.
Кевін

10

Спінлок - це тип блокування, зокрема, такий, який досягається за допомогою опитування.

Опитування - це метод перевірки статусу чогось (запитання про статус, на відміну від очікування, коли йому повідомлять статус).

Не всі опитування - це спінкінг, наприклад, опитування стану клавіш клавіатури.


Крім того, опитування не є по суті поганим. Дуже короткі періоди опитування можуть уникнути дорогих зрушень у контексті, які потребують використання переривань, не кажучи вже про те, що опитування іноді може бути простішим у здійсненні і тим самим легше підтримувати, особливо на нижчих рівнях. Як завжди, абсолюти - це жахлива річ, і вам слід скористатися методом, який забезпечує відповідну торгівлю продуктивністю / складністю для ваших потреб, як ви їх виміряли , а не сліпо використовувати або відкидати варіанти.


5

Спінлок відрізняється від опитування тим, що він відбувається лише за дуже короткий проміжок часу, порядку декількох мілісекунд або менше. Опитування може тривати нескінченно.

У паралельному програмуванні короткий епізод спінінгу часто кращий для блокування, оскільки це дозволяє уникнути витрат на переключення контексту та переходи ядра.

Подальше читання
SpinLock та SpinWait в C #
Spinlocks та Lock-Write Locks в C


Я думаю, ти мав намір сказати мікросекунди. Для блокування, який триває цілу мілісекунд, ми повинні використовувати реалізацію блокування, яка робить ядро ​​запереченням.
Петро

@ Петер Можливо, саме так мав на увазі Албахарі. Про це говорить його текст.
Роберт Харві

4

Різниця полягає в тому, що спінлок є (сподіваємось), застосовується лише в ситуаціях, коли це доречно, і в цих ситуаціях він дуже ефективний.

Ви використовуєте спінлок, якщо очікуєте, що ресурс буде заблокований лише дуже короткий час - наприклад, якщо блокування використовується лише для оновлення змінної. Спінлок блокує опис блокування з максимальною швидкістю, але, сподіваємось, не менше мікросекунд. Для виклику ОС потрібна нормальна мутекс. Якщо блокування утримується лише невеликий проміжок часу, тоді спінлок блокує лише невеликий час процесора, тоді як виклик ОС займе більше часу. Але якщо це очікування помилкове, то спінлок дуже неефективний - він використовуватиме 100% часу процесора на одному процесорі, тоді як звичайний мутекс забирає лише час для входу в ОС і повернення.

Іноді обидва поєднуються; ви запускаєте блокування віджиму ненадовго і переходите до іншої стратегії, якщо спінлок не працює.


2

Надмірне опитування - це те, чого не варто робити, оскільки він марнує системні ресурси. Звідси випливає, що опитування добре, якщо воно не витрачає системні ресурси .

Наприклад, надмірне опитування отримає завантаження процесора до 100% у випадках, коли фактична робота призведе до завантаження лише 2%.

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

SpinLock - це не окремий випадок. Якщо у нас є SpinLock, і один потік потрапляє в замок, а інший повинен зачекати, SpinLock - це неправильний вибір, якщо і лише якщо нитка, що очікує, витрачає системні ресурси. Нитка, що чекає, витратить системні ресурси тоді і лише тоді, коли їй доведеться чекати значну кількість часу, перш ніж вона зможе придбати замок.

Тому використання SpinLock для захисту всього, що вимагає декількох тисяч тактових циклів або більше, перш ніж він знову розблокується (наприклад, компілювання та виконання фрагмента javascript під час руху) є поганим, саме з тієї причини, яку ви вказали. Але використовувати SpinLock для захисту чогось, що швидко завершується, наприклад, доступ до правильно реалізованої хеш-карти - це добре, тому що чекаюча нитка закрутиться лише 2 або 3 рази і, отже, не витрачає системні ресурси.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.