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

我正在写一个库,其中:

  • 它需要在各种不同的平台 / Java实现上运行(常见的情况可能是使用Windows或Linux的Intel 64位计算机上的OpenJDK或Oracle Java)
  • 实现高性能是一个优先事项 ,因为我关心对象访问中的CPU缓存行效率
  • 在某些区域,将遍历/处理相当大的小对象图形 (假设大约1GB)
  • 主要工作量几乎完全是读取
  • 读取将分散在对象图中,但不是完全随机的(即,将存在重要的热点,偶尔读取到不常访问的区域)
  • 多个线程将同时访问 (但不修改)对象图。 没有锁定,假设不会发生并发修改。

设计小对象是否有一些经验法则/指南,以便在这种环境中有效利用CPU缓存线?

我对正确调整和构造对象特别感兴趣,因此例如最常访问的字段适合第一个缓存行等。

注意:完全清楚这是依赖于实现的,我需要进行基准测试,以及过早优化的一般风险。 无需浪费任何进一步的带宽指出这一点。 🙂

高速缓存行效率的第一步是提供参考局部性(即保持数据彼此接近)。 这在JAVA中很难做到,几乎所有东西都是通过引用分配和访问的系统。

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

  1. 将非引用类型(即int,char等)作为对象中的字段
  2. 将对象保存在数组中
  3. 保持你的对象小

在处理单个对象和遍历对象图中的对象引用时,这些规则至少会确保一些引用局部性。

另一种方法可能是根本不使用对象作为数据,但是对于通常是类中的字段的每个项具有全局非ref类型数组(大小相同),然后每个实例将由公共索引标识进入这些数组。

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

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

最好的祝福

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

免责声明:lib的作者。

Interesting Posts