我正在编写一个库,其中:
- 它将需要在范围广泛的不同平台/Java 实现上运行(常见情况可能是在装有 Windows 或 Linux 的 Intel 64 位机器上运行 OpenJDK 或 Oracle Java)
- 实现高性能是当务之急,在某种程度上我关心对象访问中的 CPU 缓存行效率
- 在某些区域,将遍历/处理相当小对象的大图(假设大约 1GB 规模)
- 主要工作量几乎完全是读取
- 读取将分散在整个对象图中,但并非完全随机(即会有重要的热点,偶尔会读取到不常访问的区域)
- 对象图将由多个线程同时访问(但不修改)。没有锁定,假设不会发生并发修改。
是否有一些设计小对象的经验法则/指南,以便它们在这种环境中有效地利用 CPU 缓存行?
我对正确调整对象的大小和结构特别感兴趣,例如最常访问的字段适合第一个缓存行等。
注意:我完全意识到这取决于实现,我需要进行基准测试,以及过早优化的一般风险。无需浪费任何进一步的带宽来指出这一点。 :-)
最佳答案
提高缓存行效率的第一步是提供引用位置(即保持数据彼此靠近)。这在 JAVA 中很难做到,因为 JAVA 几乎所有内容都是系统分配的,并通过引用访问。
为避免引用,以下内容可能很明显:
- 将非引用类型(即 int、char 等)作为您的字段 对象
- 将对象保存在数组中
- 保持你的对象小
在处理单个对象和遍历对象图中的对象引用时,这些规则至少会确保某些引用位置。
另一种方法可能是根本不对您的数据使用对象,而是为每个通常是您类中的字段的项目使用全局非引用类型数组(相同大小),然后每个实例将被识别这些数组的公共(public)索引。
然后为了优化数组或其 block 的大小,您必须知道 MMU 特性(页面/缓存大小、缓存行数等)。我不知道 JAVA 是否在系统或运行时类中提供此信息,但您可以在启动时将此信息作为系统属性传递。
当然,这与您在 JAVA 中通常应该做的完全正交:)
最好的问候
关于java - 优化 Java 对象以提高 CPU 缓存行效率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14096960/