2016-10-27 5 views
2

Я сейчас читаю C++ Concurrency in Action книга Anthony Williams и существует несколько реализаций структур без блокировки. В прямом направлении главы о блокировках свободных структур данных в книге Энтони пишут:В каких обстоятельствах блокировка данных с данными быстрее, чем блокировка?

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

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

В каких обстоятельствах блокировка свободной структуры данных является более оптимальной и должна быть предпочтительной?

+1

Какое количество данных? Как долго блокировочные версии были заблокированы? – doctorlove

+0

"должно быть предпочтительнее?" Должно быть очень сильное слово – UKMonkey

+0

Мне нравятся блокированные структуры данных, потому что они помогают избежать взаимных блокировок мьютексов. Они будут медленнее, когда будет много споров, как с прямыми замками. –

ответ

2

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

  • Разногласия должна быть высокой
  • Там должно быть достаточно ядер процессора, так что спиннинг нить может работать бесперебойно (в идеале, должен быть прикреплен к его собственному сердечнику)
1

Дизайн мьютекса будет очень редко, если когда-либо выйдет без блокировки. Итак, вопрос о том, почему кто-нибудь когда-либо использовал мьютекс, а не беззаконный дизайн?

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

+2

«Дизайн мьютекса будет очень редко, если вообще выйдет без блокировки». Я не думаю, что это правда. Похоже, чисто основано на «теории», а не на опыте. Прежде всего «блокировка» на самом деле не блокируется, блокировка выполняется на аппаратном уровне. Второй «незаблокированный» не означает «без задержки» – Slava

+2

Если создание блокировки без структуры данных означает, что для обычных простых операций теперь требуется последовательность атомарных операций, маловероятная структура данных может действительно выиграть от использования блокировок. –

+0

Вы оба правы, отсюда «редко, если когда-либо». – UKMonkey

1

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

+0

@Martin Nyolt Спасибо за указание на опечатку! Я исправил свою ошибку. –

+0

@Donghui Zhang Вы правы, это сильно зависит от количества потоков и размера данных, хранящихся в каждом узле. Я тестировал с 1000 потоков чтения и записи, и все это выглядит по-разному в пользу дизайна без блокировки. – bobeff

1

зависит от вероятности столкновения.

если столкновение очень вероятно, то мьютекс является оптимальным решением. Например: 2 потока постоянно толкают данные в конец контейнера. С фиксированной свободой только 1 нить будет успешной. Другой должен повторить попытку. В этом случае блокировка и ожидание будут лучше.

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

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

Например, если у вас есть ограничение x == y, которое необходимо, чтобы быть правдой, вы не можете использовать атомные переменные х и у, потому что вы не можете изменить обе переменные сразу, в то время как замок() будет удовлетворять ограничению