Подтвердить что ты не робот

Оптимизация объектов Java для эффективности кеша ЦП

Я пишу библиотеку где:

  • Ему нужно будет работать на различных платформах/Java (общий случай, скорее всего, будет OpenJDK или Oracle Java на 64-битных машинах Intel с Windows или Linux)
  • Достижение высокой производительности - это приоритет, в той степени, в которой меня волнует эффективность линии кэша ЦП в доступе к объекту.
  • В некоторых областях пройдены/обработаны довольно большие большие графики небольших объектов (скажем, около 1 ГБ шкалы)
  • Основная рабочая нагрузка почти исключительно читается
  • Чтения будут разбросаны по графу объектов, но не полностью случайным образом (т.е. будут значимые горячие точки, причем случайные чтения будут отображаться в менее часто посещаемых областях).
  • График объектов будет доступен одновременно (но не изменен) несколькими потоками. Нет блокировки, исходя из предположения, что одновременная модификация не произойдет.

Существуют ли какие-либо правила большого пальца/рекомендации для проектирования небольших объектов, чтобы они эффективно использовали линии кэша ЦП в этой среде?

Мне особенно интересны правильная калибровка и структурирование объектов, так что, например, наиболее часто используемые поля вписываются в первую строку кэша и т.д.

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

4b9b3361

Ответ 1

Первым шагом на пути к эффективности кэширования является предоставление ссылочной локальности (т.е. поддержание ваших данных близко друг к другу). Это трудно сделать в JAVA, где почти все системно распределено и доступно по ссылке.

Чтобы избежать ссылок, может быть очевидным следующее:

  • имеют не ссылочные типы (т.е. int, char и т.д.) как поля в вашем объекты
  • сохранить свои объекты в массивах
  • сохранить свои объекты небольшими

Эти правила, по крайней мере, обеспечат некоторую ссылочную локальность при работе над одним объектом и при обходе ссылок на объекты в графе объектов.

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

Затем для оптимизации размера массивов или их фрагментов вам необходимо знать характеристики MMU (размер страницы/кеш, количество строк кэша и т.д.). Я не знаю, предоставляет ли JAVA это в классах System или Runtime, но вы можете передать эту информацию как системные свойства при запуске.

Конечно, это полностью ортогонально тому, что вы обычно делаете в JAVA:)

С наилучшими пожеланиями

Ответ 2

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

Отказ от ответственности: автор lib.