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