Что именно делает «Mutex Lock»? - PullRequest
7 голосов
/ 26 марта 2012

Вы можете посмотреть интересную таблицу по этой ссылке. http://norvig.com/21-days.html#answers

Таблица, описанная,
Mutex блокировка / разблокировка 25 nanosec
извлечение из основной памяти 100 nanosec

нсек
Я удивился, потому что mutex lock быстрее, чем fetch data from memory. Если да, то что именно делает 1011? А что означает Mutex lock за столом?

Ответы [ 2 ]

15 голосов
/ 26 марта 2012

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

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

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

Теперь о том, как реализованы мьютексы. Мьютекс обычно реализуется с разделяемой памятью. Существует некоторый общий непрозрачный объект данных, называемый мьютексом, и функции mutex_lock и mutex_unlock обе получают указатель на один из них. Функция mutex_lock проверяет и изменяет данные внутри мьютекса с помощью атомарной последовательности команд test-and-set или load-connected / store-conditional (в x86 часто используется xhcg), и либо «получает мьютекс» - устанавливает содержимое объекта мьютекса, чтобы указать другим потокам, что критическая секция заблокирована - или должна ждать. В конце концов, поток получает мьютекс, выполняет работу внутри критической секции и вызывает mutex_unlock. Эта функция устанавливает данные внутри мьютекса, чтобы пометить их как доступные, и, возможно, пробуждает спящие потоки, которые пытались получить мьютекс (это зависит от реализации мьютекса - некоторые реализации mutex_lock просто вращаются в строгом взгляде на xchg до тех пор, пока мьютекс не станет доступен, поэтому mutex_unlock не нужно никому уведомлять).

Почему блокировка мьютекса будет быстрее, чем выход в память? Короче кеширование. Процессор имеет кэш, к которому можно получить очень быстрый доступ, поэтому операция xchg не требует полного доступа к памяти, если процессор может гарантировать, что нет другого процессора, обращающегося к этим данным. Но у x86 есть понятие «владеть» строкой кэша - если процессор 0 владеет строкой кэша, любой другой процессор, который хочет использовать данные в этой строке кэша, должен проходить через процессор 0. Таким образом, нет необходимости в xhcg Операция просмотра любых данных вне кеша, и доступ к кешу имеет тенденцию быть очень быстрым, поэтому получение неоспоримого мьютекса происходит быстрее, чем доступ к памяти.

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

1 голос
/ 26 марта 2012

В статье, на которую вы ссылались, архитектура не упоминается, но, судя по упоминаниям о кешах L1 и L2, это Intel. Если это так, то я думаю, что под мьютексом они подразумевали инструкцию LOCK. В этом отношении этот пост кажется актуальным: Intel 64 и IA-32 | Атомарные операции, включая семантику получения / выпуска

Также Руководство разработчика программного обеспечения Intel может помочь, если вы знаете, что ищете. Я прочел что-нибудь важное, что мог найти об инструкции LOCK.

...