在 Java 代码中,我可以执行哪些操作来优化 CPU 缓存?
在编写Java程序时,我是否对CPU如何利用其缓存来存储我的数据有影响?例如,如果我有一个经常被访问的数组,如果它足够小以容纳一个高速缓存行(在 64 位计算机上通常为 128 字节),它是否有帮助?如果我将一个经常使用的对象保持在该限制内,我是否可以期望其成员使用的内存靠近并保留在缓存中?
背景:我正在构建一个压缩的数字树,它在很大程度上受到C语言中的Judy数组的启发。虽然我主要追求它的节点压缩技术,但Judy将CPU缓存优化作为中心设计目标,节点类型以及它们之间切换的启发式方法受到这一点的严重影响。我想知道我是否也有机会获得这些好处?
编辑:到目前为止,答案的一般建议是,当你像在Java中一样远离机器时,不要试图对机器级细节进行微优化。我完全同意,所以觉得我必须添加一些(希望)澄清的评论,以更好地解释为什么我认为这个问题仍然有意义。这些如下:
由于计算机的构建方式,有些事情通常更容易处理。我见过Java代码在压缩数据(从内存)上运行得明显更快,即使解压缩必须使用额外的CPU周期。如果数据存储在磁盘上,很明显为什么会这样,但当然在RAM中它是相同的原理。
现在,计算机科学有很多关于这些东西的东西要说的,例如,引用的地方性在C中很好,我想它在Java中仍然很棒,如果它有助于优化运行时做更聪明的事情,也许更是如此。但是你如何完成它可能非常不同。在 C 语言中,我可能会编写代码来管理较大的内存块本身,并对相关数据使用相邻指针。
在Java中,我不能(也不想)知道很多关于特定运行时将如何管理内存的信息。因此,我还必须将优化提升到更高的抽象级别。我的问题基本上是,我该怎么做?对于引用的局部性,在我正在Java中处理的抽象级别上,“紧密结合”是什么意思?同一个对象?同一类型?相同的阵列?
总的来说,我不认为抽象层会改变“物理定律”,比喻说。在 Java 中,每次空间不足时,将数组大小加倍也是一个很好的策略,即使您不再调用也是如此。malloc()