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

mik*_*era 13 java optimization performance cpu-cache

我正在写一个库,其中:

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

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

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

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

小智 10

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

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

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

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

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

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

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

最好的祝福