Когда pthread_spin_lock подходит для использования (например, мьютекс pthread)? - PullRequest
37 голосов
/ 07 июля 2011

Учитывая, что pthread_spin_lock доступен, когда я буду его использовать, а когда не следует их использовать?

т.е. как я решу защитить некоторую общую структуру данных с помощью мьютекса pthread или спин-блокировки pthread?

Ответы [ 4 ]

45 голосов
/ 07 июля 2011

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

  1. При разблокировке нет необходимости проверять, могут ли другие потоки ожидать блокировки и пробуждать их.Разблокировка - это просто одна атомарная инструкция записи.
  2. Неспособность немедленно получить блокировку не переводит ваш поток в спящий режим, поэтому он может получить блокировку с гораздо меньшей задержкой, как только она станет доступной.
  3. Нет риска загрязнения кэша при входе в пространство ядра для сна или пробуждения других потоков.

Точка 1 всегда будет стоять, но точки 2 и 3 имеют несколько меньшую полезность, если выучтите, что хорошие реализации мьютекса, вероятно, будут вращаться приличное количество раз, прежде чем обращаться к ядру за помощью в ожидании помощи.

Теперь длинный ответ:

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

Поэтому я буду осторожен с спин-блокировками ... :-)

14 голосов
/ 07 июля 2011

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

TL; DR: зависит.

7 голосов
/ 05 октября 2012

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

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

И POSIX (PTHREAD_MUTEX_ADAPTIVE_NP), и Win32 (SetCriticalSectionSpinCount) имеют адаптивные мьютексы, многие платформы не имеют спин-блокировки POSIXAPI.

1 голос
/ 04 октября 2012

Спинлок имеет интерес только в контексте MP. Используется для выполнения псевдоатомных задач. В монопроцессорной системе принцип следующий:

  1. Блокировка планировщика (если задача имеет дело с прерываниями, вместо этого блокируйте прерывания)
  2. Сделай мой атомный прихват
  3. Разблокировать планировщик

Но в системах MP у нас нет гарантий, что другое ядро ​​не выполнит другой поток, который может войти в наш раздел кода. Чтобы предотвратить это, была создана спин-блокировка, ее цель - отложить выполнение других ядер, предотвращая проблему параллелизма. Критическим разделом становится:

  1. Блокировка планировщика
  2. SpinLock (предотвратить вход других ядер)
  3. Моя задача
  4. SpinUnlock
  5. Task Unlock

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...