Я пытаюсь использовать std:: atomic library.
Ответ 2
В чем разница между специализированными и неспецифическими функциями атомных членов?
Как видно из обобщения этих классов на стандарте (§ 29.5), существует три разных набора функций-членов:
- наиболее общий вариант обеспечивает только операции хранения, загрузки, обмена и сравнения;
- специализации для интегральных типов обеспечивают атомные арифметические и побитовые операции, в дополнение к общим,
- специализация для указателей предоставляет арифметические операции указателя в дополнение к общим.
Какая разница (если есть) между следующими функциями?
operator=
хранит значение в атомном объекте (функция открытого члена) v.s. store
(С++ 11) атомарно заменяет значение атомного объекта неатомным аргументом (функция публичного участника)
(...)
Основное функциональное различие заключается в том, что версии, не содержащие оператор (§ 29.6.5, абзацы 9-17 и более), имеют дополнительный параметр для указания желаемого порядка памяти (§ 29.3/1). В версиях оператора используется порядок упорядочивания последовательной последовательности:
void A::store(C desired, memory_order order = memory_order_seq_cst) volatile noexcept;
void A::store(C desired, memory_order order = memory_order_seq_cst) noexcept;
Требуется: аргумент порядка не должен быть memory_order_consume
, memory_order_acquire
, а не memory_order_acq_rel
.
Эффекты: Атомно заменяет значение, на которое указывает объект, или этим значением со значением. Память зависит от значение order
.
C A::operator=(C desired) volatile noexcept;
C A::operator=(C desired) noexcept;
Эффекты: store(desired)
Возвращает: desired
Неоператорные формы являются предпочтительными, поскольку не всегда необходима последовательная согласованность и потенциально более дорогостоящая, чем другие порядки памяти. При тщательном анализе можно узнать, какие минимальные гарантии необходимы для правильной работы и выбрать один из менее ограничительных порядков памяти, что дает больше возможностей оптимизатору.
В чем недостаток объявления переменной как атома v.s. неатомная переменная. Например, какой недостаток std::atomic<int> x
v.s. int x
? Другими словами, сколько накладных расходов атомной переменной?
Использование атомной переменной, когда регулярная переменная достаточна, ограничивает число возможных оптимизаций, поскольку атомарные переменные налагают дополнительные ограничения неделимости и (возможно) упорядочения памяти.
Использование регулярной переменной, когда требуется атомная переменная, может вводить расы данных и делает поведение undefined (§1.10/21):
Выполнение программы содержит гонку данных, если она содержит два конфликтующих действия в разных потоках, по крайней мере один из которых не является атомарным, и не происходит до другого. Любая такая гонка данных приводит к поведению undefined.
Накладные расходы атомной переменной являются вопросом качества реализации. В идеале, атомная переменная имеет нулевые служебные данные, когда вам нужны атомарные операции. Когда вам не нужны атомарные операции, любые служебные данные, которые могут иметь значение, не имеют значения: вы просто используете регулярную переменную.
У кого больше накладных расходов? Атомная переменная, v.s. нормальная переменная, защищенная мьютексом?
Нет никакой причины, чтобы атомная переменная имела больше накладных расходов, чем нормальная переменная, защищенная мьютексом: наихудший сценарий, атомная переменная реализована именно так. Но есть вероятность, что атомная переменная блокируется, что будет связано с меньшими затратами. Это свойство может быть установлено с помощью функций, описанных в стандарте в §29.6.5/7:
bool atomic_is_lock_free(const volatile A *object) noexcept;
bool atomic_is_lock_free(const A *object) noexcept;
bool A::is_lock_free() const volatile noexcept;
bool A::is_lock_free() const noexcept;
Возвращает: Истинно, если операции с объектами блокируются, в противном случае - false.
Ответ 3
Я не эксперт по этому поводу, но если я правильно понимаю, неспециализированные операции в вашей ссылке делают одну вещь атомарно, загружают, сохраняют, заменяют и т.д.
Специализированная функция выполняет две вещи атомарно, то есть они изменяют, а затем возвращают атомный объект таким образом, что обе операции происходят до того, как любой другой поток может с ними столкнуться.