优化Java对象以提高CPU缓存线效率

优化Java对象以提高CPU缓存线效率,java,performance,optimization,cpu-cache,Java,Performance,Optimization,Cpu Cache,我正在写一个图书馆,其中: 它需要在各种不同的平台上运行(常见的情况可能是在使用Windows或Linux的英特尔64位计算机上运行OpenJDK或Oracle Java) 实现高性能是一个优先事项,因为我关心对象访问中的CPU缓存线效率 在某些区域,将遍历/处理相当大的小型对象图形(比如1GB左右) 主要工作负载几乎完全是阅读 读取将分散在对象图上,但不是完全随机的(即,将有显著的热点,偶尔读取不太频繁访问的区域) 多个线程将同时访问对象图(但不修改)。假设不会发生并发修改,则不存在锁定

我正在写一个图书馆,其中:

  • 它需要在各种不同的平台上运行(常见的情况可能是在使用Windows或Linux的英特尔64位计算机上运行OpenJDK或Oracle Java)
  • 实现高性能是一个优先事项,因为我关心对象访问中的CPU缓存线效率
  • 在某些区域,将遍历/处理相当大的小型对象图形(比如1GB左右)
  • 主要工作负载几乎完全是阅读
  • 读取将分散在对象图上,但不是完全随机的(即,将有显著的热点,偶尔读取不太频繁访问的区域)
  • 多个线程将同时访问对象图(但不修改)。假设不会发生并发修改,则不存在锁定
设计小型对象是否有一些经验法则/指南,以便在这种环境中有效地利用CPU缓存线

我特别感兴趣的是正确地调整对象的大小和结构,以使最常访问的字段适合第一个缓存线等


注意:我完全知道这取决于实现,我需要对其进行基准测试,以及过早优化的一般风险。无需再浪费带宽指出这一点。:-)

提高缓存线效率的第一步是提供引用位置(即保持数据彼此接近)。这在JAVA中很难做到,因为JAVA中几乎所有的内容都是通过引用进行系统分配和访问的

为避免引用,以下内容可能很明显:

  • 将非引用类型(即int、char等)作为字段 物体
  • 将对象保持在数组中
  • 保持你的物品小
  • 在处理单个对象和遍历对象图中的对象引用时,这些规则至少可以确保某些引用位置

    另一种方法可能是根本不使用对象来处理数据,而是为每个项使用全局非ref类型的数组(大小相同),这些项通常是类中的字段,然后通过这些数组中的公共索引来标识每个实例

    然后,为了优化阵列或其块的大小,您必须知道MMU特性(页面/缓存大小、缓存线数量等)。我不知道JAVA是否在系统或运行时类中提供了这些信息,但您可以在启动时将这些信息作为系统属性传递

    当然,这与您在JAVA中通常应该做的事情完全是正交的:)


    致以最诚挚的问候

    您可能需要有关CPU各种缓存的信息,您可以使用(当前支持Intel CPU)从Java访问它。这有助于开发缓存感知算法


    免责声明:lib的作者。

    我很好奇在这个应用程序中使用Java的原理。在实现对所需数据布局的控制的过程中,每一步都将与该语言进行斗争。这种控制的程度将是微不足道的,例如在C++中。抱歉,我认为这是你必须放弃的野心。在以后的版本中(我不记得它是什么时候开始的),Hotspot会重新安排类的内部结构,以适合它认为最好的布局。@PatriciaShanahan我怀疑在任何语言中,尤其是在C++@Patricia中,这都是“微不足道的”实现。说得好。然而,由于其他原因(主要是可移植性、库、与现有应用程序的集成),我不得不使用JVM。因此,我正试图在这一约束范围内进行优化。还有C++,我确信我还是会为了不同的语言而战斗,只是因为不同的原因(复杂的对象图上的多线程GC):-看看。遗憾的是,该网站无法在平板电脑上运行(仍在使用flash)。