Полезна ли спин-блокировка в одноядерной архитектуре с одним процессором? - PullRequest
13 голосов
/ 22 июня 2009

Меня смущает функция спин-блокировки.

Спин-блокировка используется для остановки процесса перепланирования. Однако в машине с одним ядром полезно использовать спин-блокировку предотвратить переключение контекста?

Ответы [ 4 ]

10 голосов
/ 22 июня 2009

Краткий ответ: нет.

Согласно http://uw714doc.sco.com/en/man/html.3synch/Intro.3synch.html

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

От: http://blogs.microsoft.co.il/blogs/sasha/archive/2008/08/10/practical-concurrency-patterns-spinlock.aspx

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

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

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

10 голосов
/ 22 июня 2009

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

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

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

Тогда в ядре спинлокирует в обработчике прерываний, скомпилированном в no-op. Они полностью исключены, как вы могли подумать. В то же время, чтобы предотвратить гонки, спин-блокировки в остальной части ядра отключают прерывания непосредственно перед тем, как они действительно что-то вращают (потому что задачи ядра могут быть запланированы). Этим кодам нужны только спин-блокировки (в отличие от мьютексов), если они совместно используют код с обработчиком прерываний.

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

0 голосов
/ 23 июня 2009

номер

Более подробный ответ см. В " Как блокировка блокировки? " вместе с комментариями.

0 голосов
/ 22 июня 2009

Да и нет; в зависимости от того, какая операционная система присутствует, присутствует ли вообще, и чего вы пытаетесь достичь.

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

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

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

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

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

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