Когда мы говорим о доступе к памяти на современных архитектурах, мы обычно игнорируем «точное местоположение», из которого читается значение.
Операция чтения может извлекать данные из кэша (L0 / L1 / ...), ОЗУ или даже жесткий диск (например, при замене памяти).
Эти ключевые слова сообщают компилятору, какие операции сборки следует использовать при доступе к данным.
volatile
Ключевое слово, которое указывает компилятору всегда читать значение переменной из памяти, а не из регистра.
Эта «память» все еще может быть кешем, но в случаечто этот «адрес» в кеше считается «грязным», что означает, что значение изменилось другим процессором, значение будет перезагружено.
Это гарантирует, что мы никогда не прочитаем устаревшее значение.
Но, если тип объявления volatile
не является примитивным, чьи операции чтения / записи являются атомарными (в отношении инструкций по сборке, которые его читают / пишут) по своей природе, мы можем прочитать промежуточное значение (writer удалось записать только половину байтов к моменту, когда читатель прочитает его).
atomic
И компилятор видит операцию load
(чтение),в основном он делает то же самое, что и для значения volatile
, за исключением использования атомарных операций (это означает, что мы никогда не будем читать промежуточное значение).
Итак, что такоеРазница ???
Разница заключается в операциях записи между процессорами.При работе с энергозависимой переменной, если ЦП 1 устанавливает значение, а ЦП 2 считывает его, считыватель может прочитать старое значение.
Но как это может быть?Ключевое слово volatile обещает, что мы не будем читать устаревшие значения!
Ну, это потому, что писатель не опубликовал значение !И хотя читатель пытается прочитать его, он читает старый.
Когда компилятор наталкивается на операцию store
(запись) для атомарной переменной, он:
- Устанавливаетзначение атомарно в памяти
- Объявляет, что значение изменилось
После объявления все процессоры будут знать, что они должны перечитать значение переменной, потому что их кэшибыть помечен как «грязный».
Этот механизм очень похож на операции, выполняемые с файлами.Когда ваше приложение записывает в файл на жестком диске, другие приложения могут видеть или не видеть новую информацию, в зависимости от того, сбрасывало ли ваше приложение данные на жесткий диск.
Если данные не былине очищается, то он просто находится где-то в кешах вашего приложения и виден только сам по себе.Как только вы очистите его, каждый, кто откроет файл, увидит новое состояние.