В чем причина частого изложения "замков - дорогостоящая операция"?

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

Я просто смотрел это видео PDC 2009 о Parallelism и Concurrency, и здесь еще раз упоминается, что "блокировки являются дорогостоящая операция". Я сейчас встретил такую ​​фразу в разных текстах, книгах, и я слышал, что эксперты в этой области тоже говорят об этом.

Мне было интересно, что именно так дорого о получении блокировки (мьютекс или семафор)? Это факт, что он вызывает инструкцию LOCK# на уровне Ассемблера?

Это факт, что для получения блокировки требуется вызов ядра в ОС?

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

Что происходит под обложками?

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

Может ли кто-нибудь уточнить?

ПРИМЕЧАНИЕ. Мне просто интересно, я знаю, как работает потоки, и я тоже не хочу делать какую-то глупую оптимизацию.

Ответ 1

Это факт, что он вызывает команду LOCK # на уровне Ассемблера?

Нет, поскольку это не всегда так.

Это факт, что для получения блокировки требуется вызов ядра в ОС?

Нет, поскольку он обычно этого не делает.

На самом деле, замки очень, очень недорогие. Утверждают, что это дорого. Если вам нужно выбирать между блокировкой и конфликтом, большую часть времени лучше всего блокировать.

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

Например: скажем, что у вас есть четыре потока, которые готовы к запуску, A, B, C и D. Скажите, что A и B сражаются друг с другом (скажем, они манипулируют одной и той же коллекцией). И скажите, что C и D конкурируют друг с другом, но A не противоречит C. Если A и B работают одновременно (конкурируют), блокировки заставят один из них не быть готовым к запуску, планировщик будет затем планируйте C (или D), и два потока будут работать без дальнейшего раздумий. (По крайней мере, до следующего переключателя контекста.)

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

Ответ 2

Parallelism

Когда изменяемые общие данные требуют блокировки, вы можете потерять преимущества parallelism.

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

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

  • Затем добавьте часть общих данных, которая изменяется со временем. По определению, ни один из двух потоков не может изменять/читать эти данные при в то же время. Это означает, что если два потока хотят получить доступ к эти данные, у вас больше нет параллельной работы: они должны работать в сериализованный (синхронизированный) способ. Чем чаще это чем больше ваше приложение будет вести себя как однопоточное приложение, чем двухпоточное приложение.

Поэтому, когда говорят, что "блокировки - дорогостоящая операция", я полагаю, что это связано с потенциальной потерей parallelism, а не самой дорогостоящей блокировкой.

Затраты

В дополнение к потере parallelism, если вы аккумулируете небольшие, но ненулевые затраты на блокировки и потенциальную синхронизацию и контекстные переключатели, блокировки могут очень замедлить ваш алгоритм.

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

Смягчение

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

Один трюк для незаблокированных операций включает в себя выполнение всей инициализации общих данных до появления любых потоков и чтения только с этих данных после нереста.

Терминология

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

Ответ 3

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

Ответ 4

Короткий ответ: Нет, они не дорогие.

Более длинный ответ: да, они дороги, потому что если ваши блокировки бессмысленны и ничего не делают, присутствие блокировок замедлит ваш код.

Фактический ответ требует уточнения:

Техническая поддержка против внедрения и дизайна:

Технический: Дэвид Шварц отвечает, что технически блокировки не замедляют работу кода. То есть, если вы запустили однопоточный код с операторами блокировки, блокировки не замедлят вас. *

Реализация: Mark Ransom указывает на его ответ, который блокирует медленный, потому что блоки вызывают задержки, которые приводят к более медленному приложению.

Дизайн: Реальный ответ: дизайн, который включает блокировки, имеет тенденцию быть медленнее, чем проекты, которые этого не делают. Замки предназначены для замедления вашего кода.

Итак, если вы можете разумно управлять кодом, где блокировки никогда не попадают или даже не нужны, вам абсолютно необходимо. Вот почему люди говорят, что "замки дороги". Дело не в том, что оператор lock(obj) дорог, а в том, что действие блокировки других потоков является дорогостоящим и должно проводиться только в ситуациях, когда вы оценили его стоимость.

* Конечно, если вы получите конфликт в одном поточном приложении, он никогда не завершится.

Ответ 5

Замки часто являются прямыми затворами, которые заставляют нить "вращаться", не делая никакой полезной работы при блокировке.

Ничего не стоит дорого, поскольку, как всем известно: "время - деньги".