При каких обстоятельствах ОС / ЦП не приведут к возможной согласованности в энергонезависимых переменных Java на практике? - PullRequest
0 голосов
/ 09 января 2019

Мы стараемся избегать атомарности и чтения в память, когда это возможно, в нашем продукте облачных сервисов. В результате мы имеем оживленную дискуссию о практической возможной согласованности (также называемой конечной видимостью) статических переменных, когда Java работает на современных процессорах.

Принято считать, что спецификация языка Java не гарантирует либо cross-thread-update-visibility ИЛИ возможная согласованность для многопоточных изменений статических переменных области видимости UNLESS они определены как volatile. По сути, отсутствие ключевого слова volatile означает, что нет никаких гарантий относительно согласованности. Использование ключевого слова volatile обеспечивает упорядочение команд и немедленную видимость / согласованность последнего значения переменной в потоках.

Однако на практике , когда современные коммерческие ЦП записывают в статическую переменную, они помещают в очередь подсказку обновления памяти некоторой формы к контроллеру кеша, что затем в конечном итоге заставляет ячейку памяти обновляться в кеше через ядра. И если только считываемая область памяти не находится в узком цикле в определенном потоке, обычное использование ЦП при рабочих нагрузках предприятия не , по-видимому, в конечном итоге генерирует необходимые подсказки кеша для создания согласованности между потоками для энергонезависимой статической нагрузки. переменные на практике (за исключением крайних случаев оптимизации компилятора, которые вызывают странные проблемы с переупорядочением).

Например, если у нас есть несколько потоков Java, читающих статически разделяемую переменную без изменяемого квалификатора, с одним потоком, генерирующим очень широко разнесенные записи в переменную (один раз в несколько часов), то тестовый код Java последовательно показывает потоки быстро забрать изменение значения независимо от того, нет ли изменяемого квалификатора. Вероятно, это связано с тем, что базовая архитектура ОС / ЦП делает недействительной кэш-память для каждого ядра.

Таким образом, наш вопрос таков: помимо проблем с переупорядочением компилятора (например, условия завершения в циклах), может кто-нибудь пролить свет на то, когда эта ОС / ЦП не гарантируется, но на практике возможна -согласованность не произойдет?

Например, существуют ли реальные архитектуры Intel / AMD / ARM или разновидности Linux, на которых эта не гарантированная, но имеющаяся на практике конечная согласованность не будет возникать? Наши тесты показывают, что он всегда в конечном итоге создает согласованность в MacOS Linux даже без ключевого слова volatile.

1 Ответ

0 голосов
/ 09 января 2019

Современные ЦП имеют согласованную модель памяти, поэтому, если переменная записывается в память, она будет видимой (может быть изменена в любой момент в будущем, поэтому не полагайтесь на это).

На практике вам не удастся воспользоваться JIT, он может решить вообще не хранить переменные в памяти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...