Почему std :: mutex в два раза медленнее, чем CRITICAL_SECTION

std :: mutex реализован с помощью критических секций, поэтому он намного быстрее, чем OS Mutex (в Windows). Однако это не так быстро, как в Windows CRITICAL_SECTION.

Тайминги просто плотный цикл в одном потоке:

423.76ns ATL CMutex
 41.74ns std::mutex
 16.61ns win32 Critical Section

У меня вопрос: что еще делает std :: mutex? Я посмотрел на источник, но не смог его уследить. Однако были дополнительные шаги, прежде чем он перешел к Crit Sec. Мои вопросы: полезны ли эти дополнительные шаги? То есть для чего нужны дополнительные шаги; что бы я упустил, используя CRITICAL_SECTION?

Также почему они назвали это Mutex, если это не реализовано с Mutex?


person Philip    schedule 17.02.2015    source источник
comment
Который ты рассчитываешь? Создание мьютекса, его блокировка, разблокировка, ...? Что касается отличий от мьютекса Win32: мьютекс Win32 - это межпроцессный мьютекс. Стандарт требует только мьютекса между потоками, который может быть более легкой конструкцией (а Windows реализует критическую секцию).   -  person Jerry Coffin    schedule 17.02.2015
comment
CMutex реализован с мьютексом, это недешево. std :: mutex построен поверх среды выполнения с параллелизмом, это довольно большой фрагмент кода с функциональностью, которая значительно выходит за рамки примитивов потоковой передачи и планирования, предоставляемых ОС. Многослойность тяжелая, это не дается бесплатно. Если критика служит вашей цели и накладные расходы действительно имеют значение, тогда просто решите проблему и используйте ее.   -  person Hans Passant    schedule 17.02.2015
comment
Я рассчитывал просто блокировку / разблокировку. Мне просто любопытно, что std :: mutex делает за пределами критической секунды. Если это полезно, разве я не должен этого хотеть? Если это бесполезно, зачем? Думаю, я буду использовать std :: mutex, но мне просто интересно, что он делает дополнительно.   -  person Philip    schedule 17.02.2015
comment
@Philip: На самом деле единственными преимуществами являются: переносимость и то, что это присутствует в сигнатуре других функций потоковой передачи C ++.   -  person Ben Voigt    schedule 17.02.2015
comment
Тогда я думаю, потому что кроссплатформенность может быть ответом высокого уровня. Хотя мне все еще любопытно, что именно делают накладные расходы. Я догадываюсь о бухгалтерском учете?   -  person Philip    schedule 18.02.2015
comment
Какую версию компилятора и библиотеки вы используете? std :: mutex - это примитив кроссплатформенной синхронизации, и его производительность зависит от качества реализации.   -  person yohjp    schedule 18.02.2015
comment
Похоже, что он интегрирован в более широкий набор функций, например, путь кода проходит мимо параметров тайм-аутов, похоже, он реализует свой собственный планировщик, имеет очередь блокировок и т.д. мне непонятно все, что вы используете.   -  person Harry Johnston    schedule 18.02.2015


Ответы (1)


Std :: mutex обеспечивает нерекурсивную семантику владения. CRITICAL_SECTION обеспечивает рекурсивную семантику. Поэтому я предполагаю, что дополнительный уровень в реализации std :: mutex предназначен (по крайней мере частично) для устранения этой разницы.

Обновление: Пошаговое выполнение кода, похоже, std :: mutex реализовано в терминах очереди и инструкций InterlockedX, а не в классическом Win32 CRITICAL_SECTION. Несмотря на то, что std :: mutex нерекурсивен, основной код в RTL может опционально обрабатывать рекурсивные и даже временные блокировки.

person Adrian McCarthy    schedule 17.02.2015
comment
Это звучит правдоподобно, за исключением того, что в моих тестах std :: recusive_mutex не быстрее, чем std :: mutex. Это говорит о том, что они оба делают что-то, чтобы их замедлить, что ортогонально тому, рекурсивны они или нет, верно? - person Philip; 17.02.2015
comment
Поскольку UB пытается рекурсивно заблокировать std::mutex, я не понимаю, зачем нужен код для устранения разницы. - person T.C.; 17.02.2015
comment
Возможно, это отладочный код для обнаружения UB? Было ли выбрано время для выпуска или отладки? - person Adrian McCarthy; 18.02.2015
comment
Это недопустимая причина, потому что рекурсивный мьютекс удовлетворяет всей семантике обычного мьютекса, поэтому для устранения разницы не требуется дополнительный код. - person rdb; 23.05.2018