Достаточно ли абстракции «видимости», чтобы понять поведение std::memory_order?C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Достаточно ли абстракции «видимости», чтобы понять поведение std::memory_order?

Сообщение Anonymous »

Сами концепции, связанные с порядком памяти C++, а также объяснения, предоставленные местным техническим сообществом в моей стране, довольно абстрактны. По этой причине я попытался понять поведение различных порядков памяти, используя только одну концепцию видимость.
  • Код: Выделить всё

    Visibility
    : (Ниже приводится мое понимание видимости, в котором основное внимание уделяется основной концепции «быть видимым».)
    • Код: Выделить всё

      Being visible
      : После того, как поток выполняет операцию записи в общую переменную между потоками, результат модификации, вызванный этой операцией записи, может быть успешно прочитан последующей операцией чтения другого потока.
    • Примечание: Антоним «видимый» еще не видимый, а не невидимый.

      Код: Выделить всё

      Not yet visible
      означает, что модификация операции записи потока в общей переменной между потоками на данный момент не была прочитана операцией чтения другого потока (и может быть прочитана впоследствии).
    • Код: Выделить всё

      Invisible
      относится к постоянной и неотъемлемой невозможности межпоточного доступа, а локальные переменные потока (измененные thread_local) являются типичным примером «невидимого» сценария.
  • Код: Выделить всё

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

    memory_order_release
    :
    Этот порядок памяти будет «упаковывать» результаты модификации всех операций записи, которые происходят до этой операции освобождения в текущем потоке (например, операции присваивания любых других неатомарных переменных или операции Memory_order_relaxed других атомарных переменных и т. д.). Когда другой поток успешно считывает значение, записанное этой операцией освобождения, посредством соответствующего запроса/ результаты модификации этих предыдущих операций записи могут быть детерминированно видимы для этого потока.
  • Код: Выделить всё

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

    memory_order_consume
    :
    Такой порядок памяти гарантирует, что в текущем потоке все операции чтения, происходящие после этой операции потребления, могут считывать только допустимое состояние, полученное при выполнении операции потребления, если у них есть зависимость данных от значения атомарной переменной, считанной этой операцией потребления.
    Если операция чтения потребления успешно считывает значение, записанное предыдущей операцией записи выпуска, то сама операция потребления (относительно связанной с ней логики чтения) и все последующие операции в текущем потоке, данные которых зависят от значения, считанного этой операцией потребления, могут прочитать последнюю модификацию, внесенную в общую переменную потоком, владеющим операцией освобождения, до этой операции освобождения. Другими словами, все изменения, сделанные потоком, владеющим операцией Release, до операции Release, детерминированно видны операциям чтения в текущем потоке, которые происходят после этой операции Consumer, и имеют зависимость данных от соответствующего значения.
Подводя итог, я попытался объяснить различное поведение порядка памяти C++, используя концепцию «видимости», как я ее понимаю. Исходя из этого, мои вопросы таковы:
Вопрос 1
Может ли мое понимание «видимости» правильно объяснить поведение порядка памяти C++ в большинстве сценариев? Если мое понимание неверно или ошибочно, не могли бы вы дать точное объяснение на уровне языка C++ (а не сосредотачиваться на низкоуровневых реализациях)?
(Дополнительное примечание: в местном техническом сообществе моего региона участники всегда склонны объяснять порядок памяти C++ с помощью системных принципов низкого уровня, таких как переупорядочение инструкций компилятора, переупорядочение инструкций ЦП и непоследовательное кэширование ЦП. Однако для меня эти низкоуровневые системы подобны «черному ящику» — существуют многочисленные и сложные основные причины, которые могут привести к необычному поведению порядка памяти. Если преувеличивать, я мог бы даже случайно выдвинуть необоснованное утверждение вроде «это потому, что мой компьютер использует квантовый процессор, и нам нужно наблюдать квантовые биты, чтобы определить значение переменной». Короче говоря, я считаю, что объяснение порядка памяти C++ с помощью принципов ниже уровня языка C++ является одновременно односторонним и подвержено недоразумениям и ошибкам.)
Вопрос 2
Если мои приведенные выше объяснения, основанные на концепции «видимости», верны, как я могу объяснить поведение Memory_order_seq_cst на основании этой концепции «видимости», которую я понимаю?

Подробнее здесь: https://stackoverflow.com/questions/798 ... rs-of-stdm
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»