简而言之,我试图在用户级基准测试过程中实现以下目标(伪代码,假设 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
,然后使用RDPMC
inside读取计数器sample_pctr()
。
我遇到了第一个障碍,因为编写 MSR 需要内核权限。看起来您实际上可以从用户空间读取计数器(如果配置正确),但是配置计数器(使用 MSR)的行为需要由内核承担。
有谁知道一种轻量级的方法来要求内核从用户空间配置性能计数器,以便我可以RDPMC
在我的基准测试工具中使用?
我研究过/考虑过的东西:
- Linux 的性能工具。似乎已准备好在流程的整个生命周期内进行采样,而不是在流程中作为特定点(每次迭代之前和之后)进行采样。
- 直接使用 perf 系统调用(即
perf_event_open
)。看起来计数器值只会定期更新(使用采样率)或在计数器超过阈值后更新。在我问的那一刻,我正好需要计数器值。这就是为什么RDPMC
看起来如此吸引人的原因。我想频繁采样本身会扭曲性能计数器读数。 - PAPI建立在 perf 之上,因此可能继承了上述问题。
- 写一个内核模块——太费劲了,太容易出错了。
理想情况下,我想要一个适用于 OpenBSD 和 Linux 的解决方案,但不知何故,我认为这是一项艰巨的任务。也许现在只适用于 Linux。
非常感谢任何帮助。谢谢。
编辑:我刚刚找到了Linux msr 设备节点,这可能就足够了。如果出现更好的答案,我会留下问题。