Почему мьютекс pthread считается "медленнее", чем мьютекс? - PullRequest
39 голосов
/ 16 июня 2011

Почему мьютексы POSIX считаются тяжелее или медленнее, чем фьютексы? Откуда появляются служебные данные в типе мьютекса pthread? Я слышал, что мьютексы pthread основаны на фьютексах, и когда они не оспариваются, не делают никаких вызовов в ядро. Тогда кажется, что мьютекс pthread - это просто «оболочка» вокруг фьютекса.

Являются ли накладные расходы просто при вызове функции-обертки и что мьютекс-функция нуждается в "настройке" futex (то есть, в основном, в настройке стека для вызова функции pthread-мьютекса)? Или с мьютексом pthread происходят какие-то дополнительные шаги по защите памяти?

Ответы [ 5 ]

29 голосов
/ 16 июня 2011

Futexes были созданы для улучшения производительности мьютексов pthread.NPTL использует фьютексы, LinuxThreads - предшествующие фьютексы, которые, как мне кажется, и являются тем «более медленным» соображением.Мьютексы NPTL могут иметь некоторые дополнительные издержки, но их не должно быть много.

Редактировать: Фактические издержки в основном состоят из:

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

Итак, от нескольких циклов (типичный случай) до нескольких циклов + ошибочная ветвьвкл + дополнительная пропущенная кеша (очень худший случай).

14 голосов
/ 17 сентября 2011

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

8 голосов
/ 29 ноября 2016

Технически говоря, мьютексы pthread не медленнее и не быстрее, чем фьютексы.pthread - это просто стандартный API, поэтому то, будут ли они медленными или быстрыми, зависит от реализации этого API .

В частности, в Linux мьютексы pthread реализованы в виде фьютексов и, следовательно, быстры.На самом деле вы не хотите использовать сам API-интерфейс futex, поскольку он очень сложен в использовании, не имеет соответствующих функций-оболочек в glibc и требует кодирования в сборке, которая была бы непереносимой.К счастью для нас, сопровождающие glibc уже закодировали все это для нас под капотом API-интерфейса muth pthread.

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

Так что статистический факт состоит в том, что в большинстве операционных систем, совместимых с POSIX, мьютекс pthread реализован в пространстве ядра и медленнее, чемФутекс.В Linux они имеют одинаковую производительность.Возможно, существуют другие операционные системы, в которых мьютексы pthread реализованы в пользовательском пространстве (в непредусмотренном случае) и, следовательно, имеют более высокую производительность, но на данный момент я знаю только о Linux.

8 голосов
/ 16 июня 2011

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

Я полагаю, вы говорите о ядро ​​ темы, когда вы говорите о потоках POSIX.Вполне возможно иметь полностью пользовательскую реализацию потоков POSIX, которые не требуют системных вызовов, но имеют свои собственные проблемы.

Насколько я понимаю, futex находится на полпути между потоком ядра POSIX и потоком пользователя POSIX.

1 голос
/ 10 июля 2016

На AMD64 futex составляет 4 байта, а NPTL pthread_mutex_t составляет 56 байтов! Да, есть значительные накладные расходы.

...