c ++, c ++ 11, std :: атомарные функции-члены - PullRequest
10 голосов
/ 04 марта 2012

Я пытаюсь использовать библиотеку std :: atomic.

  1. В чем разница между специализированными и неспециализированными атомарными функциями-членами?
  2. В чем разница (если есть) междуследующие функции?
  3. operator = сохраняет значение в атомарном объекте (открытая функция-член) против store (C ++ 11) атомарно заменяет значение атомарногообъект с неатомарным аргументом (открытая функция-член)
  4. оператор T () загружает значение из атомарного объекта (открытая функция-член) vs load (C++ 11) атомарно получает значение атомарного объекта (открытая функция-член).
  5. operator + = vs fetch_add
  6. оператор- = против fetch_sub
  7. оператор & = против fetch_and
  8. оператор | = vs fetch_or
  9. operator ^ = vs fetch_xor
  10. Какова обратная сторона объявления переменной по состоянию наатомная против неатомарной переменной.Например, в чем минус std::atomic<int> x против int x?Другими словами, сколько стоят служебные данные атомарной переменной?
  11. У какой из них больше служебной информации?Атомная переменная против нормальной переменной, защищенной мьютексом?

Вот ссылка на мои вопросы.http://en.cppreference.com/w/cpp/atomic/atomic

Ответы [ 3 ]

10 голосов
/ 04 марта 2012

Не эксперт, но я попробую:

  1. Специализации (для встроенных типов, таких как int) содержат дополнительные операции, такие как fetch_add. Неспециализированные формы (определяемые пользователем типы) не будут содержать их.
  2. operator= возвращает аргумент, store - нет. Также неоператоры позволяют вам указывать порядок памяти. Стандарт гласит: operator= определяется как store.
  3. То же, что и выше, хотя возвращается значение load.
  4. То же, что и выше
  5. То же, что и выше
  6. То же, что и выше
  7. То же, что и выше
  8. То же, что и выше
  9. То же, что и выше
  10. Они делают разные вещи. Неопределенное поведение использовать int так же, как вы бы использовали std::atomic_int.
  11. Можно предположить, что накладные расходы составляют int <= std::atomic <= int and std::mutex, где <= означает «меньше накладных расходов». Так что это, вероятно, лучше, чем блокировка мьютексом (особенно для встроенных типов), но хуже, чем int.
9 голосов
/ 16 октября 2012

В чем разница между специализированными и неспециализированными атомарными функциями-членами?

Как видно из краткого описания этих классов в стандарте (§29.5), существует три различныхнаборы функций-членов:

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

В чем разница (если есть) междуследующие функции?

operator= сохраняет значение в элементарном объекте (открытая функция-член), а store (C ++ 11) атомарно заменяет значение атомарного объекта неатомарным аргументом (publicфункция-член)

(...)

Основное функциональное отличие состоит в том, что неоператорская версияons (§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

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

Какова обратная сторона объявления переменной какатомарный против неатомарной переменной.Например, в чем минус std::atomic<int> x против int x?Другими словами, сколько стоят служебные данные атомарной переменной?

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

Использование обычной переменной, когда требуется атомарная переменная, может привести к гонкам данных, и это делает поведение неопределенным (§1.10 / 21):

Выполнениепрограммы содержит гонку данных , если она содержит два конфликтующих действия в разных потоках, по крайней мере одно из которых не является атомарным, и ни одно из них не происходит раньше другого.Любая такая гонка данных приводит к неопределенному поведению.

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

Какая из них имеет больше накладных расходов?Атомная переменная против нормальной переменной, защищенной мьютексом?

Нет никаких причин для того, чтобы у атомной переменной было больше служебных данных, чем у нормальной переменной, защищенной мьютексом: в худшем случаереализовано просто так.Но есть вероятность того, что атомная переменная не блокируется, что потребует меньше накладных расходов.Это свойство может быть установлено с помощью функций, описанных в стандарте в §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.

0 голосов
/ 04 марта 2012

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

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

...