我正在写一个库,其中:
- 它将需要运行在广泛的不同平台/ Java 实现(常见情况可能是运行 Windows 或 Linux 的 Intel 64 位计算机上的 OpenJDK 或 Oracle Java)
- 实现高性能是首要任务,就我关心对象访问中的CPU缓存线效率而言
- 在某些地区,相当小物体的大图将被遍历/处理(假设大约 1GB 规模)
- 主要工作量是几乎只阅读
-
阅读会分散跨越对象图,但不是完全随机的(即会有显着的热点,偶尔会读取不经常访问的区域)
- 对象图将是同时访问(但未修改)由多个线程。假设不会发生并发修改,则不存在锁定。
是否有一些设计小对象的经验法则/指南,以便它们在这种环境中有效地利用 CPU 缓存线?
我对正确调整对象的大小和结构特别感兴趣,以便例如最常访问的字段适合第一个缓存行等。
Note: I am 充分意识这是依赖于实现的,我需要进行基准测试,以及过早优化的一般风险。无需再浪费任何带宽来指出这一点。 :-)
提高缓存行效率的第一步是提供引用局部性(即保持数据彼此靠近)。这在 JAVA 中很难做到,因为几乎所有东西都是系统通过引用分配和访问的。
为了避免引用,以下内容可能是显而易见的:
- 将非引用类型(即 int、char 等)作为字段
物体
- 将对象保存在数组中
- 保持你的物体小
这些规则至少可以确保在处理单个对象以及遍历对象图中的对象引用时具有一定的引用局部性。
另一种方法可能是根本不使用对象来存储数据,而是为每个项目使用全局非引用类型数组(大小相同),这些项目通常是类中的字段,然后每个实例将由公共索引标识到这些数组中。
然后,为了优化数组或其块的大小,您必须了解 MMU 特性(页面/缓存大小、缓存行数等)。我不知道 JAVA 是否在系统或运行时类中提供此信息,但您可以在启动时将此信息作为系统属性传递。
当然,这与您通常在 JAVA 中应该做的事情完全正交:)
此致
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)