В многоядерных системах x86 реализованы мьютексы с использованием инструкции LOCK? - PullRequest
9 голосов
/ 29 июля 2011

В сборке x86 есть префикс LOCK, который можно применить к инструкции, чтобы сделать ее атомарной.Это атомарность во всех ядрах?Какова обычная задержка?Для обычного мьютекса какая инструкция заблокирована?

Спасибо.PS: меня учили, что в системах, где нет такой инструкции, мьютексы все еще можно делать, но это более трудоемкоИнтересно, кто-нибудь еще так поступит?

Ответы [ 2 ]

9 голосов
/ 29 июля 2011

В x86 префикс блокировки блокирует все ядра и допускает атомарность.Для реализации этого в других системах без LOCK, используются CMPXCHG циклы или узкие циклы с логикой повторения, которые пытаются установить значение чего-либо на ожидаемое значение.Как вы можете видеть, 2-й способ более вреден в большинстве случаев, так как он просто постоянно повторяет попытки установить значение (и продолжает делать это до тех пор, пока не завершится).Для x86 задержка минимальна и может варьироваться от остановки конвейера команд или его очистки до последующего выполнения этой инструкции атомарно (обычно за несколько циклов), 2-й метод не может быть оценен, так как он зависит от степени раздоразначение, которое необходимо изменить атомарно.Для мьютекса я считаю, что это значение флага, которое должно быть получено (проверьте, что мьютекс не получен, и непрерывно ждите, пока мьютекс не будет запущен, затем попытайтесь атомарно изменить флаг, чтобы получить его).

AFAIK Процессоры IBM используют 2-й метод, так как при работе с ядром Linux я обнаружил, что функция атомарного приращения использует его (возможно, только для старых процессоров).Платформа x86 по-прежнему использует

lock addl ...;

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

2 голосов
/ 23 апреля 2018

В сборке x86 есть префикс LOCK, который можно применить к инструкции, чтобы сделать ее атомарной.Это атомарность для всех ядер?

Да.

Какова обычная задержка?

Стоимость варьируется в зависимости от нескольких факторов(Модель процессора, скорость процессора, скорость шины, скорость ОЗУ, где данные на самом деле находятся в данный момент и что еще пытается использовать шина).Для очень старых процессоров (8086, 80186, 80286, 80386) не было кэшей, а LOCK заблокировал шину, чтобы ничто другое не могло помешать.Это не стоило бы намного больше, чем та же самая инструкция без LOCK, за исключением того, что все остальное, пытающееся использовать команду на время выполнения инструкции, должно было ждать (это замедляло все остальное больше, чем замедляло сам код)..

Для всех современных процессоров (я полагаю, «Pentium III или более поздняя версия») он был изменен, чтобы по возможности полагаться на протокол когерентности кэша MESI.В частности, строка кеша переносится в кеш и переводится в «эксклюзивное» состояние, затем инструкция выполняется с использованием только локального кеша без блокировки шины.Стоимость зависит от того, где находятся данные - например, если они уже находятся в кеше данных L1 того же ЦП (а не в кешах других ЦП), то LOCK может ничего не стоить.Однако (из-за природы многопроцессорного кода) часто строка кеша находится в кеше другого ЦП и должна быть перенесена из одного кеша в другой и / или признана недействительной в кешах другого ЦП (через. Что называется «чтение для»).владение "в протоколе когерентности кэша MESI), поэтому он стоит дороже (но все же не так много, как блокировка шины).

Для обычного мьютекса какая инструкция заблокирована?

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

Обратите внимание, что когда вы не можете получить мьютекс, ядру сказано не давать вашей задаче никакого времени ЦП, пока мьютекс не будет освобожден;и затем, когда мьютекс освобождается, ядру необходимо сообщить, что задача может снова потреблять процессорное время.Это имеет гоночные условия и заканчивается атомарной «проверкой возможности получения мьютекса и последующим изменением состояния задачи» глубоко в планировщике ядра.

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

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

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