如何从Java进程中找到一级缓存线的大小?

如何从Java进程中找到一级缓存线的大小?,java,caching,cpu,Java,Caching,Cpu,我感兴趣的是微调缓存感知数据结构(例如,请参见或Herlihy等人的无锁跳过树),以及防止(例如)在并发阵列处理期间。我已经知道如何通过“sun.arch.data.model”属性找到JVM指针大小,但是我还没有找到确定一级缓存中缓存线大小的方法 请注意,这些信息并不重要,因为我可以继续使用一级缓存线大小的保守估计值(微调有缓存意识的数据结构时为64字节,防止错误共享时为256字节);但是,如果很容易获得一级缓存属性,那么我也可以利用它。您可以做的是一个简单的循环,以给定的步幅从内存中读取单个

我感兴趣的是微调缓存感知数据结构(例如,请参见或Herlihy等人的无锁跳过树),以及防止(例如)在并发阵列处理期间。我已经知道如何通过“sun.arch.data.model”属性找到JVM指针大小,但是我还没有找到确定一级缓存中缓存线大小的方法


请注意,这些信息并不重要,因为我可以继续使用一级缓存线大小的保守估计值(微调有缓存意识的数据结构时为64字节,防止错误共享时为256字节);但是,如果很容易获得一级缓存属性,那么我也可以利用它。

您可以做的是一个简单的循环,以给定的步幅从内存中读取单个字节。如果跨距为1(字节),则必须在每次迭代中支付一次换行惩罚。如果您加倍跳过,您可以期望一半的性能,因为现在您每相同的迭代次数获取两次行

一旦您的步幅达到缓存线大小,您应该会看到性能降级停止,因为您将达到每次迭代获取一行的级别,并且再次加倍步幅不会改变它,您只需跳过行。这样做的一个问题是,您可能会在CPU中触发一个HW流预取器,并让缓存线提前在较低的缓存级别等待您,因此我希望看到斜率减小,但不会完全变直。当跨距为缓存线大小的两倍时,这可能会消失,因为您可能会比某些流预取器更快,从而动摇它们(仍可能有跨距预取器“帮助”您更进一步,但影响应该会大大减小)


还请记住,您的代码应该运行在比最后一级缓存大的数据集(例如,一个数组)上,几MB就足够了。

我认为这项(非常有趣,甚至可以说是令人兴奋的)任务的实现成本太高。我会在这里做一件懒惰的事情:为CPU模型确定硬代码缓存大小,并确定它——因为这可能更容易。但是,如果JVM在某种类型的VM中运行,而这种VM隐藏了实际的CPU模型,那么这可能会出错,而您的解决方案将在该场景中使用正确的大小…行大小就是行大小;在什么意义上是64和256?@OliCharlesworth如果我不知道精确的线大小,那么我会根据我试图完成的任务使用不同的估计值,例如,如果我正在微调缓存感知数据结构,那么我将使用64字节的较低估计值,因为这样,如果实际行大小大于64字节,数据结构仍将表现良好,如果我要防止错误共享,那么我将使用更高的256字节估计值,因为如果实际行大小小于256字节,这仍然会表现良好。