Я запутался с документацией для .NET / C# относительно ключевого слова volatile
против System.Threading.Thread.VolatileRead
/ VolatileWrite
и System.Threading.Volatile.Read/Write
. Я пытаюсь понять, что именно гарантировано для изменчивого поля и что именно делают эти методы.
Я думал, volatile
предоставляет семантику выпуска / приобретения, но документацию для Thread.VolatileRead
/ VolatileWrite
заставляет меня задуматься, верно ли мое понимание.
Это справочник по языку для volatile: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/volatile
Добавление модификатора volatile гарантирует, что все потоки будет наблюдать изменчивые записи, выполненные любым другим потоком в порядке, в котором они были выполнены. Нет гарантии единого общего порядка изменчивых записей, как видно из всех потоков выполнения.
Пока что имеет смысл. Это языковая спецификация: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/classes#volatile -поля
Для энергозависимых полей такая оптимизация переупорядочения ограничена:
Чтение энергозависимого поля называется изменчивое чтение. Изменчивое чтение имеет «приобретенную семантику»; то есть гарантированно произойдет до любых ссылок на память, которые появляются после нее в последовательности команд. Запись изменяемого поля называется изменяемой записью. У изменчивой записи есть "семантика выпуска"; то есть гарантированно произойдет после любых ссылок на память перед инструкцией записи в последовательности команд.
Эти ограничения гарантируют, что все потоки будут наблюдать энергозависимые записи, выполняемые любым другим потоком в том порядке, в котором они были выполнила. Соответствующая реализация не обязана обеспечивать одно общее упорядочение изменчивых записей, как видно из всех потоков выполнения.
Опять же, похоже, что volatile
обеспечивает семантику освобождения / получения.
Но потом я смотрю документацию для Thread.VolatileRead: https://docs.microsoft.com/en-us/dotnet/api/system.threading.thread.volatileread?view=netframework-4.8#System_Threading_Thread_VolatileRead_System_Int64__
Считывает значение поля. Значение является последним, записанным любым процессором в компьютере, независимо от количества процессоров или состояния кэша процессора. ... В многопроцессорной системе VolatileRead получает самое последнее значение, записанное в ячейку памяти любым процессором. Для этого может потребоваться очистка кэшей процессора.
Для Thread.VolatileWrite:
Немедленно записывает значение в поле, так что это значение отображается для всех процессоров компьютера. .
Это выглядит более строгим, чем индивидуальное ограничение хранения / загрузки (освобождение / приобретение), в частности, часть, касающаяся очистки кэшей процессора, т.е. более строгая гарантия, чем просто volatile
. Но затем тот же документ гласит:
В C# использование модификатора volatile в поле гарантирует, что весь доступ к этому полю использует VolatileRead или VolatileWrite
Так что мой Вопрос в том, что гарантировано для поля volatile
относительно буфера хранилища - просто отпустите / заполучите или более сильные гарантии Thread.VolatileRead / Write? Или мое понимание о VolatileRead/Write
неверно и совпадает с volatile
?