Модель памяти Java-volatile и x86
Я пытаюсь понять внутреннюю природу Java volatile и ее семантику, а также ее трансальтацию к базовой архитектуре и ее инструкциям. Если мы рассмотрим следующие блоги и ресурсы
Заборы генерируются для летучих, что генерируется для чтения / записи volatile и вопрос переполнения стека на заборах
Вот что я понял:
- volatile read вставляет loadstore / loadload барьеры после него (инструкция LFENCE на x86)
- это предотвращает переупорядочивание нагрузок с последующими записями / нагрузками
- предполагается гарантировать загрузку глобального состояния, которое было изменено другими потоками , т. е. после LFENCE изменения состояния, выполненные другими потоками, видны текущему потоку на его процессоре.
Вот что я пытаюсь понять: Java не излучает LFENCE на x86 то есть чтение volatile не вызывает LFENCE .... Я знаю, что память упорядочивает x86 предотвращает переупорядочивание грузов с lods / stored, поэтому второй пункт маркера заботится. Однако я бы предположил, что для того, чтобы состояние было видно этим потоком, должна быть выдана инструкция LFENCE, чтобы гарантировать, что все буферы нагрузки будут опустошены до следующей инструкции после выполнения ограждения (в соответствии с руководством Intel). Я понимаю, что есть протокол когерентности cahce на x86, но volatile read все равно должен сливать любые нагрузки в буферы, нет?
1 ответ:
На x86 буферы закреплены в строке кэша. Если строка кэша потеряна, значение в буфере не используется. Таким образом, нет необходимости ограждать или сливать буферы; значение, которое они содержат, должно быть текущим, потому что другое ядро не может изменить данные, не сделав сначала недействительной строку кэша.