Подтвердить что ты не робот

Являются ли атомарные переменные блокируемыми?

Когда мы говорим об атомных переменных, таких как С++ 11 atomic<>, свободен ли он? Или что-то другое? Если я буду управлять очередью с помощью атомных переменных, будет ли она медленнее, чем свободная от очереди очередь?

4b9b3361

Ответ 1

В стандарте не указывается, не блокируются ли атомарные объекты. На платформе, которая не обеспечивает блокировки атомных операций для типа T, объекты atomic<T> могут быть реализованы с использованием мьютекса, который не будет блокироваться. В этом случае любые контейнеры, использующие эти объекты в своей реализации, также не будут заблокированы.

Стандарт предоставляет возможность проверить, является ли переменная atomic<T> незафиксированной: вы можете использовать var.is_lock_free() или atomic_is_lock_free(&var). Эти функции гарантированно всегда возвращают одно и то же значение для того же типа T при выполнении данной программы. Для базовых типов, таких как int, имеются также макросы (например, ATOMIC_INT_LOCK_FREE), которые указывают, доступен ли доступ к ядерному доступу к этому типу.

Ответ 2

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

atomic<T> переменные не используют блокировки (по крайней мере, там, где T является атомарным на вашей платформе), но они не блокируются в указанном выше смысле. Вы можете использовать их в реализации контейнера без блокировки, но они недостаточны сами по себе.

Например, atomic<queue<T>> не превратит обычный std::queue в структуру данных без блокировки. Однако вы могли бы реализовать действительно незакрепленный atomic_queue<T>, членами которого были atomic.

Обратите внимание, что даже если atomic<int> изначально атомарно и не эмулируется с блокировкой на вашей платформе, это не делает его незаблокированным каким-либо интересным способом. Обычная int уже не блокируется в этом смысле: оболочка atomic<> получает явное управление упорядочением памяти и доступ к примитивам аппаратной синхронизации.

Ответ 3

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

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

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

"Lock free" продает мечты wanabee программистам с жесткой оболочкой. Мне очень забавно, что механизм, который действительно полагается на блокировку многопроцессорной шины, может быть назван так.

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

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

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

Но если вы начнете разбрызгивать шинные замки повсюду или (не дай бог!) опросить переменные с шиной как дешевую и легкую замену для надлежащих объектов синхронизации (что супер-крутой г-н без ожидания мог бы назвать "заваривание ваших собственные домашние шпильки в 3 простых шага" ), вам удастся превратить все новейшие аппаратные средства, которыми ваш код работает в эмулятор Pentium я 1995 года.