4

简而言之,我试图在用户级基准测试过程中实现以下目标(伪代码,假设 x86_64 和 UNIX 系统):

results[] = ...
for (iteration = 0; iteration < num_iterations; iteration++) {
    pctr_start = sample_pctr();
    the_benchmark();
    pctr_stop = sample_pctr();
    results[iteration] = pctr_stop - pctr_start;
}

FWIW,我正在考虑使用的性能计数器是CPU_CLK_UNHALTED.THREAD_ALL,读取独立于时钟频率变化的核心周期数(在较早的问题中,我一直计划为此使用 TSC 寄存器,但唉,这不是这个寄存器措施)。

我最初的意图是使用内联汇编器首先配置一个计数器 using WRMSR,然后使用RDPMCinside读取计数器sample_pctr()

我遇到了第一个障碍,因为编写 MSR 需要内核权限。看起来您实际上可以从用户空间读取计数器(如果配置正确),但是配置计数器(使用 MSR)的行为需要由内核承担。

有谁知道一种轻量级的方法来要求内核从用户空间配置性能计数器,以便我可以RDPMC在我的基准测试工具中使用?

我研究过/考虑过的东西:

  • Linux 的性能工具。似乎已准备好在流程的整个生命周期内进行采样,而不是在流程中作为特定点(每次迭代之前和之后)进行采样。
  • 直接使用 perf 系统调用(即perf_event_open)。看起来计数器值只会定期更新(使用采样率)或在计数器超过阈值后更新。在我问的那一刻,我正好需要计数器值。这就是为什么RDPMC看起来如此吸引人的原因。我想频繁采样本身会扭曲性能计数器读数。
  • PAPI建立在 perf 之上,因此可能继承了上述问题。
  • 写一个内核模块——太费劲了,太容易出错了。

理想情况下,我想要一个适用于 OpenBSD 和 Linux 的解决方案,但不知何故,我认为这是一项艰巨的任务。也许现在只适用于 Linux。

非常感谢任何帮助。谢谢。

编辑:我刚刚找到了Linux msr 设备节点,这可能就足够了。如果出现更好的答案,我会留下问题。

4

1 回答 1

0

似乎最好的方法——至少对于 Linux 来说——是使用msr 设备节点

您只需打开一个设备节点,查找所需 MSR 的地址,然后读取或写入 8 个字节。

OpenBSD 更难,因为(在撰写本文时)MSR 没有用户空间代理。因此,您需要编写内核模块或手动实现 sysctl。

于 2016-08-19T11:21:55.157 回答