Насколько я понимаю, когда происходит обратная запись из кеша в основную память, он будет записывать весь блок кеша. Это может включать байты / слова, которые также не были изменены, так как грязный бит устанавливается для блока кеша в целом.

При этом я предполагаю, что архитектуры ЦП обычно не отслеживают «грязь» на байтовом уровне. Не стесняйтесь исправить мое предположение, если все существующие архитектуры действительно отслеживают на байтовом уровне.

Скажем, два java-поля, скажем a и b, находятся рядом и имеют один и тот же тег. Таким образом, при кешировании они будут помещены в один и тот же блок кеширования.

Скажем, в ядре запущен поток, который обновляет только значение a, но не b. Тогда действительно ли значение как a, так и b будет обновлено в основной памяти из кеша? Или в java есть что-то, что гарантирует, что обновляется только значение a, учитывая, что изменяется только a?

Есть ли здесь роль Java? Или все зависит от архитектуры процессора?

Моя точная проблема

Предположим изначально, a=1, b=1 Скажем, у нас есть два потока T1 и T2. T1 делает только одно, он устанавливает a=2. Точно так же T2 делает b=2.

Предположим, у нас есть многоядерная среда с ядрами C1 и C2, на которых работают T1 и T2 соответственно. Оба кешируют значения a=1, b=1.

Скажем, T1 финиширует первым. Кэш C1 записан обратно. Итак, теперь в основной памяти: a=2, b=1. Теперь Т2 финиширует. Теперь, когда кеш записывается обратно, устанавливает ли он a=1, b=2, потому что в кэше C2 было a=1?

Или у Java есть гарантия от этого?

Предположим, что отношения «Не происходит до / после» не установлены. Никакой синхронизации, нестабильности или чего-то еще в этом роде.

Не стесняйтесь исправлять любое из моих предположений.

2
jubatus 28 Фев 2021 в 19:36

1 ответ

Лучший ответ

Nitpicking: теоретически записи не должны идти в основную память; они могут оставаться в кэше неограниченное время в зависимости от используемого алгоритма согласованности кеша.

Проблема, о которой вы говорите, называется разрывом слов, и JVM должна защищать от нее.

Ознакомьтесь со следующими ссылками:

Я не знаком с другими архитектурами, но на X86 загрузка и сохранение могут выполняться на уровне байтов. N-байтовое поле всегда будет n-байтовым; поэтому он никогда не будет разделен на 2 строки кэша. А поскольку логическое значение в Java хранится в байтах, разрыв слов не может происходить на X86.

1
pveentjer 28 Фев 2021 в 17:50