Барьер памятиБарьер памяти (англ. memory barrier, membar, memory fence, fence instruction) — вид барьерной инструкции, которая приказывает компилятору (при генерации инструкций) и центральному процессору (при исполнении инструкций) устанавливать строгую последовательность между обращениями к памяти до и после барьера. Это означает, что все обращения к памяти перед барьером будут гарантированно выполнены до первого обращения к памяти после барьера. Барьеры памяти необходимы, так как большинство современных процессоров использует оптимизации производительности, которые могут привести к переупорядочиванию инструкций. Также переупорядочивание обращений к памяти может быть вызвано компилятором в процессе оптимизации использования регистров целевого процессора. Такие перестановки обычно не влияют на корректность программы с одним потоком исполнения, но могут вызвать непредсказуемое поведение в многопоточных программах. Правила изменения порядка исполнения инструкций зависят от архитектуры. Некоторые архитектуры предоставляют несколько типов барьеров с различными гарантиями. Например, amd64 предоставляет следующие инструкции: Барьеры памяти, как правило, используются при реализации примитивов синхронизации, неблокирующих структур данных и драйверов, которые взаимодействуют с аппаратным обеспечением. ПримерСледующая программа исполняется на двух процессорах. Изначально ячейки памяти Процессор #1: while (f == 0) { }
// Здесь необходим барьер
print x;
Процессор #2: x = 42;
// Здесь необходим барьер
f = 1;
Хотя ожидается, что Оптимизации порядка исполнения компиляторомБарьеры памяти работают только на аппаратном уровне. Компиляторы могут также переупорядочить инструкции как часть оптимизации программы. Меры по предотвращению переупорядочивания необходимы только для данных, которые не защищены примитивами синхронизации. В языках С и C++ ключевое слово volatile предназначено для исключения оптимизаций компилятора. Используется чаще всего для работы с отображаемым в память вводом-выводом. Однако данное ключевое слово (в отличие от Java) никак не обеспечивает атомарности и защиты от внеочередного исполнения.[3] Примечания
|