确定纯Java中处理器缓存的大小

时间:2013-07-28 13:08:38

标签: java performance cpu-cache

我很好地在纯Java中使用对每核处理器缓存的大小非常敏感的数值算法:当工作数据集适合L1缓存时,它运行得明显更快。

显然,我可以通过一些基准测试对我的本地机器进行微调。但理想情况下,我希望能够根据所用处理器的L1缓存大小自动调整工作集的大小。

本机代码不是一个选项:用Java编写这个算法的全部意义在于使它与平台无关!

纯Java 中有可靠的方法可靠地确定每核心缓存的大小吗?

2 个答案:

答案 0 :(得分:5)

如果使用一组参数比另一组参数更快地运行 ,那么我会根据注意到的差异进行调整。在开始进行一系列长时间的计算之前(我假设是这种情况,否则你不会在意),运行具有各种不同大小的内部数据存储的较小集合。 (我假设算法可以像数字那样进行调整。)

这样,差异来自L1高速缓存大小,或者L1 + L2高速缓存大小,还是完全不同的东西并不重要 - 你会选择最适合当前情况的任何东西。

您需要小心JIT预热期,就像在正常的基准测试中一样,但我认为这是创建通用优化方法的好方法,即使它最终发生了最重要的L1缓存。

您可能将此作为单独的安装时工作,将结果写入配置文件,以便在后续运行中可以避免额外的工作。 (您可能想要一种重新运行调整步骤的方法,以防处理器发生变化或其他情况。)

答案 1 :(得分:0)

public class CacheLine {
    public static void main(String[] args) {
        CacheLine cacheLine = new CacheLine();
        cacheLine.startTesting();
    }

    private void startTesting() {
        byte[] array = new byte[128 * 1024];
        for (int testIndex = 0; testIndex < 10; testIndex++) {
            testMethod(array);
            System.out.println("--------- // ---------");
        }

    }

    private void testMethod(byte[] array) {
        for (int len = 8192; len <= array.length; len += 8192) {

            long t0 = System.nanoTime();
            for (int i = 0; i < 10000; i++) {
                for (int k = 0; k < len; k += 64) {
                    array[k] = 1;
                }
            }

            long dT = System.nanoTime() - t0;
            System.out.println("len: " + len/1024 + " dT: " + dT + " dT/stepCount: " + (dT) / len);
        }
    }
}

此代码可帮助您确定L1数据缓存大小。 您可以在此处详细了解它。 https://medium.com/@behzodbekqodirov/threading-in-java-194b7db6c1de#.kzt4w8eul