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

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

заборы, созданные для volatile, что генерируется для чтения / записи volatile и вопрос переполнения стека на заборах

вот что я понял:

  • volatile читать вставки loadStore / loadload барьеры после него (инструкция LFENCE на x86)
  • это предотвращает переупорядочивание нагрузок с последующими записями / нагрузками
  • предполагается гарантировать загрузку глобального состояния, которое было изменено другими потоками т. е. после LFENCE изменения состояния, выполненные другими потоками, видны текущему потоку на его CPU.

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

1 ответов


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