Из ветки
Volatile и предупреждение C5220Автор: Евгений Музыченко
Дата: 31.12.21
Давайте без срача "для портабельного кода нужен atomic" / "не хочу портабельный код, у меня всё работает".
По стандарту, volatile не имеет отношения к атомартности и memory ordering, т.е. не годится для многопоточной синхронизации.
Начиная с Visual Studio 2005, volatile является как бы атомиком с acquire/release семантикой.
В более поздних Visual Studio добавлен флаг /volatile:ms и /volatile:iso
/volatile:ms обеспечивает acquire/release семантику, и установлен по умолчанию на x86
/volatile:iso не обеспечивает acquire/release семантику, и установлен по умолчанию на ARM
Атомарность на самом деле гарантируется для правильно выровненных 32-битных типов, и 64-битных типов на x64.
Memory ordering гарантии бесплатны на x86 и не бесплатны на ARM, поэтому логика в /volatile:iso для ARM понятна.
Вопрос собственно:
а к чему приведёт включение /volatile:iso на x86?
Вроде как на первый взгляд ни к чему:
* атомарность есть
* на уровне процессора acquire/release уже есть на x86 из-за total store order
* компилятор не переставляет volatile переменные относительно друг друга (не имеет право)
* компилятор не переставляет volatile переменные относительно другого кода (имеет право, но не был за этим замечен)
Пока только следующиее предположение. С некоторых пор компилятор компилятор создаёт метаданные для эмуляции x86 кода на ARM.
Есть недокументированная опция /volatileMetadata и /volatileMetadata- для управления этим (по умолчанию оно включено).
/volatileMetadata- отключает метаданные, что приводит к тому, что любые переменные становятся атомиками, что замедляет выполнение.
Возможно, при включенной опции /volatileMetadata эти метаданные не создаются для /volatile:iso кода, то есть, volatile не сработает для эмуляции как acquire-release.