Кто-нибудь точно знает об этом?
Конечно, существует множество источников, например Справочник по C ++:
memory_order_relaxed Расслабленная операция: нет ограничений на синхронизацию или упорядочение, налагаемых на другие операции чтения или записи, гарантируется только атомарность этой операции.
memory_order_consume Операция загрузки с этим порядком памяти выполняет операцию потребления в затронутой области памяти: никакие операции чтения или записи в текущем потоке, зависящие от текущего загруженного значения, не могут быть переупорядочены перед этой загрузкой. Записи в зависимые от данных переменные в других потоках, которые освобождают ту же атомарную переменную, видны в текущем потоке. На большинстве платформ это влияет только на оптимизацию компилятора.
memory_order_acquire Операция загрузки с этим порядком памяти выполняет операцию получения в затронутой области памяти: никакие операции чтения или записи в текущем потоке не могут быть переупорядочены до этой загрузки. Все записи в других потоках, которые выпускают ту же атомарную переменную, видны в текущем потоке.
memory_order_release Операция сохранения с этим порядком памяти выполняет операцию освобождения: никакие операции чтения или записи в текущем потоке не могут быть переупорядочены после этого сохранения. Все записи в текущем потоке видны в других потоках, которые получают ту же атомарную переменную, а записи, несущие зависимость в атомарной переменной, становятся видимыми в других потоках, которые используют ту же атомарную переменную.
memory_order_acq_rel Операция чтения-изменения-записи с этим порядком памяти является как операцией получения, так и операцией освобождения. Никакие операции чтения или записи в памяти в текущем потоке не могут быть переупорядочены до или после этого сохранения. Все записи в других потоках, которые освобождают одну и ту же атомарную переменную, видны до модификации, а модификация видна в других потоках, которые получают ту же атомарную переменную.
memory_order_seq_cst Операция загрузки с этим порядком памяти выполняет операцию получения, хранилище выполняет операцию освобождения, а чтение-изменение-запись выполняет как операцию получения, так и операцию освобождения, плюс один общий порядок существует в при этом все потоки наблюдают за всеми изменениями в одном и том же порядке.
Также ознакомьтесь с atomic ‹> Презентация оружия от Херба Саттера, которая многое объясняет.
Также мне нужно знать, в какое место компилятор ставит забор памяти.
Это зависит от архитектуры. На некоторых архитектурах это не операция, на некоторых это префикс инструкции, на некоторых это будет специальная инструкция до / после загрузки / сохранения.
Существует статья под названием «Барьеры памяти: аппаратное обеспечение для Software Hackers ", который анализирует препятствия на многих архитектурах, если вам интересно.
Например: atomic.load(std::memory_order_acquire);
означает применить memory_order_acquire ограждение и загрузить данные атомарно?
Это тоже зависит от архитектуры, но для барьера получения я бы сказал прямо противоположное: мы загружаем переменную, а затем следим за тем, чтобы до загрузки не было дальнейших операций чтения / записи, то есть ставим забор.
Но на некоторых платформах это может быть инструкция одного процессора. Например, на ARM есть инструкции загрузки (LDA) и сохранения-выпуска (STL).
person
Andriy Berestovskyy
schedule
11.02.2018