如何使用Java收集AMD CPU的缓存命中率?

3

我正在使用Java编写程序。

在这个程序中,我正在读取和修改一组数据。以下是代码示例:

public double computation() {
    char c = 0;
    char target = 'a';
    int x = 0, y = 1;

    for (int i = 0; i < data.length; i++) {
        // Read Data
        c = data[index[i]];

        if (c == target)
            x++;
        else
            y++;

        //Change Value
        if (Character.isUpperCase(c))
            Character.toLowerCase(c);
        else
            Character.toUpperCase(c);

        //Write Data
        data[index[i]] = c;
    }
    return (double) x / (double) y;
}

顺便说一下,INDEX数组包含DATA数组的索引,以随机顺序防止预取。我使用INDEX数组中的随机索引来强制所有缓存访问都被错失

现在我想通过收集有关CPU缓存命中率的信息来检查其行为。

是否有开发出的工具可以实现此目的?如果没有,是否有任何技术可用?

2个回答

1
在Linux上,可以通过 OProfile 收集这样的信息。每个CPU都有性能事件计数器。请参阅此处以获取AMD K15家族事件列表:http://oprofile.sourceforge.net/docs/amd-family15h-events.php
OProfile 定期对事件计数器进行采样,并与程序计数器一起使用。在程序运行后,您可以分析发生了多少事件以及(统计上)在哪个程序位置。
OProfile 具有内置的Java支持。它与Java JIT交互,并创建一个合成符号表来查找生成的JIT代码的Java方法名称。
初始设置并不容易。如果感兴趣,我可以指导您或写更多关于它的内容。

这是我两年前的一个旧项目。当时我使用了PAPI,虽然它并没有提供最精确的结果,但对于我的目的来说还是不错的。我希望你的答案能帮助到其他人。 - Reza

1

我认为你无法从Java中获取这样低级别的信息,但可能有人知道更好的方法。你可以编写相同的程序,避免缓存未命中,并检查差异。例如,在此其他帖子中,这就是我建议的。


我如何确保我的所有数据都已被缓存?我不知道你是否理解这段代码的目的,但我正在使用 INDEX 数组中的随机索引强制使我的所有缓存访问都失败。我的意思是你的建议听起来不错,但难道不应该有一个工具来处理这样的情况吗? - Reza
@Hesam 你能举一个现实世界中需要知道这个的程序示例吗? - Peter Lawrey
@PeterLawrey 任何需要高速计算的地方!在我的情况下,线程迁移会产生很多开销,这取决于缓存行为。我认为我应该检查缓存访问的命中率,以获得最佳性能。 - Reza
@PeterLawrey,为了让自己清楚,我某种程度上找到了一个工具,但是没有下载链接。THOR - Reza
为了解决这个问题,我使用线程亲和性将关键线程分配给CPU以防止迁移。如果没有任何控制手段,我不知道您的系统性能有多糟糕。 - Peter Lawrey
@PeterLawrey,事实上我最近看到并使用了你的库。ThreadAffinity :D。我正在开发一段实验性代码! - Reza

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接