Модель памяти Java - volatile и x86

Я пытаюсь понять внутренности java volatile и ее семантики, а также ее трансляцию к базовой архитектуре и ее инструкциям. Если мы рассмотрим следующие блоги и ресурсы

ограждения, созданные для volatile, Что генерируется для чтения/написать volatile и Вопрос о переполнении стека на заборы

вот что я собираю:

  • volatile read inserts loadStore/LoadLoad барьеры после него (инструкция LFENCE на x86)
  • Он предотвращает переупорядочение нагрузок с последующей записью/загрузкой
  • Предполагается гарантировать загрузку глобального состояния, которое было изменено другими потоками, то есть после LFENCE изменения состояния, сделанные другими потоками, видны текущему потоку на его процессоре.

Чего я пытаюсь понять, так это: Java не выделяет LFENCE на x86  то есть считывание volatile не вызывает LFENCE.... Я знаю, что упорядочение памяти x86 предотвращает запись нагрузок с помощью логов/хранимых данных, поэтому берется вторая точка маркера. Тем не менее, я бы предположил, что для того, чтобы состояние было видимым в этом потоке, должна быть выдана инструкция LFENCE, чтобы гарантировать, что все буферы LOAD слиты до следующей инструкции после того, как забор будет выполнен (согласно руководству Intel). Я понимаю, что есть протокол cahce coherence на x86, но волатильное чтение все равно должно разряжать любые нагрузки в буферах, нет?

Ответы

Ответ 1

В x86 буферы привязаны к строке кэша. Если строка кэша потеряна, значение в буфере не используется. Поэтому нет необходимости заслонять или сливать буферы; значение, которое они содержат, должно быть текущим, потому что другое ядро ​​не может изменять данные без первой аннулирования строки кэша.