如何读取英特尔处理器的PMC(性能监视计数器)?

5

我正在尝试使用RDMSR和WRMSR指令读取PMC(性能监视计数器)。

在我的Linux桌面上,我的CPU是Intel i7 6700(Skylake),我编写了一个简单的驱动程序代码:

static int my_init(void)
{
    unsigned int msr;
    u64 low, high;

    msr = 0x187;
    low = 0x412e;
    high = 0x0;

    asm volatile("1: wrmsr\n"
            "2:\n"
            : : "c" (msr), "a"(low), "d" (high) : "memory");

    msr = 0xC2;
    asm volatile("1: rdmsr\n"
            "2:\n"
            : "=a" (low), "=d" (high) : "c" (msr)); 

    printk("val: %lu\n", (low) | ((high) << 32));

    return  0;
}

参考英特尔手册(《Intel® 64和IA-32架构软件开发人员手册第3B卷:系统编程指南》中的18.2“架构性能监视”),在上述代码中,我将“0x412e”(L3缓存未命中数)写入“0x187”(IA32_PERFEVTSEL1 MSR),并读取“0xC2”(IA32_PMC1 MSR)。
然而,根据手册,缓存未命中数必须在EAX: EDX中返回(EAX包含低位),实际上,低(EAX)和高(ECX)值的值都返回为0。
我想知道如何使用MSR对(IA32_PERFEVTSELx和IA32_PMCx)监视英特尔CPU的性能事件。更具体地说,缓存未命中数是我的目标。
如果您有任何想法,请给予建议,感谢。

4
顺带一提,你不必自己编写驱动程序。除了 Linux 的 perf 子系统之外,已经有一些直接访问实现可以让您编程性能计数器,然后通过用户空间的 rdpmc 直接读取它们。例如 https://github.com/obilaniu/libpfc(由 SO 用户 @Iwillnotexist 编写),被 @BeeOnRope 的 uarch-bench 使用。还有 Agner Fog 的 testp 工具(http://agner.org/optimize/#testp)。 - Peter Cordes
谢谢您的评论。我会检查一下宏程序,通过使用它,我认为实现我的目标会变得更加容易。 - nickeys
2个回答

7
你的PERFEVTSEL1编程不完整。 PERFEVTSEL1 至少,你应该在第22位启用计数:
  • EN(启用计数器)标志(第22位)-设置时,性能计数在相应的性能监视计数器中启用;清除时,相应的计数器被禁用。

哇……你给了我一个很好的指针!我会立即尝试。非常感谢你。 - nickeys

-1

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