Для уточнения:
volatile
представляет собой концепцию, С и сообщает компилятор принести переменный каждый раз, когда из памяти, а затем использовать «компилятор сгенерированного» кэшированные версии в регистрах или оптимизировать определенный код.
Что может вызвать путаницу здесь, это кеширование процессора или кеши программ (переменные a.k.a в регистрах).
Кэш CPU/Hardware на 100% прозрачен для программы, и аппаратное обеспечение обеспечивает 100% синхронизацию. Там не о чем беспокоиться, когда вы выписываете load
из памяти, а данные поступают из кеша ЦП, тогда это те же данные, что и в адресной памяти.
Ваш компилятор может решить хотя бы «кэшировать» часто используемые переменные в регистрах, которые затем могут выйти из синхронизации с памятью, потому что аппаратное обеспечение не знает об этом. Это то, что предотвращает ключевое слово volatile
. Обычный пример:
int * lock;
while (*lock) {
// do work
// lock mot modified or accessed here
}
оптимизирующий компилятор увидит, что вы не используете в цикле lock
и преобразовать это:
if (*lock)
while (true) {
// do work
}
Это, очевидно, не поведение вы хотите, если lock
должен быть измененный, например, другой поток. SO, вы отмечаете его летучие, чтобы предотвратить это:
volatile int * lock;
while (*lock) {
// do work
}
Надеюсь, что это немного упростит.
Означает ли это, что сама ОС заботиться о кеше должна быть синхронной? мы всегда будем получать правильное значение переменной после объявления volatile. Из-за кеша не будет проблем. –
Аппаратное обеспечение позаботится о любых проблемах с когерентностью кеширования, а не ОС. Но да, никогда не будет проблем с аппаратным кешем. Вы можете немного прочитать об этом здесь: http://en.wikipedia.org/wiki/Cache_coherence –
Большое спасибо ... –