Меня смущает функция блокировки спина.
Блокировка спина используется, чтобы остановить процесс перепланировки. Однако в машине с одним сердечником полезно использовать блокировку спина для предотвращения переключения контекста?
Меня смущает функция блокировки спина.
Блокировка спина используется, чтобы остановить процесс перепланировки. Однако в машине с одним сердечником полезно использовать блокировку спина для предотвращения переключения контекста?
Короткий ответ: нет.
Согласно http://uw714doc.sco.com/en/man/html.3synch/Intro.3synch.html
Блокировки отжима не должны использоваться в одной процессорной системе. В лучшем случае, прямая блокировка на одной процессорной системе будет тратить ресурсы, замедляя владельца блокировки; в худшем случае он затормозит процессор.
В однопроцессорных системах спин-блокировки не нужны, потому что синхронизация спин-спина требуется только на высоких IRQL. На высоких IRQL (выше диспетчеризации IRQL) переключатель контекста не может произойти, поэтому вместо того, чтобы откручивать поток ниши, можно просто запросить прерывание на соответствующем IRQL и вернуть; прерывание будет замаскировано до тех пор, пока освобождающий поток не снизит IRQL ниже запрошенного IRQL.
Для однопроцессорных систем ядро будет игнорировать значение счетчика спинов и рассматривать его как ноль - по существу, сделать спин-блокировку no-op.
Да, прядильные замки могут быть полезны и повысить эффективность некоторых операций. Однако, как правило, вы должны начать с мьютекса, и если профилирование покажет, что это узкое место, вы можете подумать о спин-блокировке.
Ваше наблюдение хорошее: в однопроцессорной системе нет смысла вращаться, чтобы ждать ресурса, потому что вы можете переключать потоки раньше, чем позже. Мьютексы и семафоры делают именно это.
В многопроцессорной системе поток на другом процессоре может освободить блокировку без переключения контекста. Spinlocks могут быть полезны, тогда, если вы не ожидаете долгого ожидания, потому что быстрее может просто повесить, пока другой поток не разблокирует вещь. Если вы идете спать на мьютексе, вы в основном уверены, что какое-то значительное мертвое время, прежде чем вы будете перенесены.
В коде ядра, однако, ситуация меняется: обработчики прерываний должны обращаться к общим ресурсам с остальной частью ядра, но они не могут спать. Мьютексы помещают ядро в спящий режим, поэтому вы не можете их использовать, но spinlocks не полезны ни потому, что ничто не прерывает обработчик прерываний на однопроцессорном (ну, может быть, другое прерывание, но это страшно).
В ядре, тогда, spinlocks внутри обработчика прерываний компилируются в no-op. Они полностью исчезли, как вы думаете. В то же время, чтобы предотвратить гонки, спин-блокировки в остальной части ядра отключают прерывания непосредственно перед тем, как они действительно что-то вращаются (потому что задачи ядра могут быть запланированы). Эти коды нуждаются только в шпильках (в отличие от мьютексов), если они совместно используют код с обработчиком прерываний.
В общем, вы правы: spinlocks действительно не имеют особого смысла в однопроцессорном режиме, если у вас есть мьютексы, потому что мьютексы тратят меньше времени.
Да и нет; в зависимости от того, какая операционная система присутствует, если таковая присутствует вообще, и чего вы пытаетесь достичь.
Если у вас есть роскошь полной многозадачной и многопоточной операционной системы, вы должны выбрать свои примитивы из коллекции, которую она вам предоставляет, или вы рискуете неэффективностью в лучшем случае и неработоспособной синхронизацией в худшем случае. Каждая ОС имеет свои идиомы и предпочтительные механизмы, и несоблюдение этих соглашений также может иметь затраты.
Чем дальше вы получаете от полного ядра (или глубже в ядро и драйверы устройств, которые вы получаете), вы обнаружите, что лучшие идиомы включают примитивы синхронизации нижнего уровня.
Даже одноядерный процессор имеет обработчики прерываний, которые могут выполнять (в принципе) между любыми парами инструкций или даже во время некоторых инструкций с несколькими циклами в некоторых архитектурах. Это фактически своего рода concurrency, хотя и слабее второго ядра, поэтому примитивы синхронизации необходимы при общении между потоком (передними) переднего плана и любыми обработчиками прерываний в фоновом режиме. Конечно, в одном ядре синхронизация между передними потоками должна включать контекстный переключатель.
Ожидание условия, установленного в обработчике прерываний или в состоянии, установленном в аппаратном регистре, - это оба случая, когда один поток переднего плана в одном ядре может не иметь лучшего выбора, чем вращаться по флагову или регистру.
Изменить: Я попытался прояснить этот ответ, чтобы было ясно, что речь идет о синхронизации в целом больше, чем о любой конкретной реализации ОС спин-блокировки. Вопрос не в том, какая ОС (если таковая имеется) и не помечена для какой-либо конкретной ОС.
Нет.
Для более подробного ответа см. "" Как блокировать блокировку?" вместе с комментариями.