memory_order_relaxed load vs volatile load

В чем разница между чтением значения atomic_uint с memory_order_relaxed и чтением значения volatile unsigned int (предполагая, что летучие операции являются атомарными)?

В частности, давайте определим:

Решение 1

  1. Поток «писатель» пишет в atomic_uint (с любым классификатором порядка памяти, от memory_order_relaxed до memory_order_seq_cst)
  2. Поток «читатель» делает атомное расслабленное чтение на том же atomic_uint

Решение 2

  1. Поток «писатель» пишет в volatile unsigned int
  2. Поток «reader» читает это значение

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

Единственное отличие, которое я вижу:

  • энергозависимые операции не могут быть переупорядочены между ними, в то время как атомная нагрузка может быть переупорядочена с другими атомарными операциями

Есть что-то еще?

3

Решение

Нестабильное чтение не гарантированно будет атомарным. Это означает, что вы можете прочитать значение, которое никогда не записывалось в переменную (а также никогда не могло быть записано какой-либо частью вашей программы). Например. если ваше приложение только когда-либо пишет 0xAAAAAAAA или же 0xBBBBBBBB переменной, изменчивое чтение может привести к 0xAAAABBBB, Или действительно что-нибудь еще, так как стандарт не определяет поведение, когда изменчивые чтения и записи появляются в разных потоках без других средств синхронизации.

Я не знаю, говорит ли стандарт, что это UB или определенная реализация. Я могу только сказать, что есть реализации (например, MSVC 2005), которые определяют поведение для несинхронизированных энергозависимых операций чтения / записи как расширение.

2

Другие решения

Использование memory_order_relaxed по сути, дает хорошо управляемую изменчивую переменную для связи между потоками:

  • volatile определено в терминах ABI (Application Binary Interface), это внешний интерфейс; летучие вещества — это интерфейсы с внешним миром: доступ к такому объекту является частью наблюдаемого поведения и никогда не может быть оптимизирован;
  • атомика хорошо определена чисто в терминах внутренней семантики; представление объектов не является частью спецификации; доступ к такому объекту является частью абстрактной машины и иногда может быть оптимизирован или внутренне обоснован (компилятором в терминах семантики C / C ++).
0

По вопросам рекламы [email protected]