我可以从 Windows 中的用户模式程序中读取 CPU 性能计数器吗?

Posted

技术标签:

【中文标题】我可以从 Windows 中的用户模式程序中读取 CPU 性能计数器吗?【英文标题】:Can I read the CPU performance counters from a user-mode program in Windows? 【发布时间】:2017-08-01 03:41:29 【问题描述】:

我想对所有最新的 x86 硬件上提供的hardware performance counters 进行编程和阅读。

在 Linux 上,有各种 perf_events 系统可以执行此操作(perf 实用程序可以从未经修改的程序外部执行此操作)。

Windows 中有没有这样的内置工具?如果不存在内置工具,那么第二好的方法可能是使用第三方代码的另一种方法,但这不需要我让驱动程序签名。

【问题讨论】:

快速谷歌搜索:youtube.com/watch?v=c1In6NbJt5E&t=2581s msdn.microsoft.com/en-us/library/windows/desktop/… @MichaelPetch - 我看到了,但似乎他们不是在谈论“硬件 PMU 计数器”,而是更高级别的性能计数器,它们主要报告在软件中跟踪的操作系统和框架级别的东西。但是,我想证明是错误的! @BeeOnRope 我读的太快了,否则我会发布这个:msdn.microsoft.com/en-us/library/windows/desktop/… @MichaelPetch - 我不认为它真的有效(除非你是一个足够大的公司)。从该页面:要配置硬件性能计数器,您需要一个驱动程序来配置计数器。即使我愿意编写这样的驱动程序并支付代码签名证书,所需的证书也不是发给个人。 【参考方案1】:

简答

不,Windows 中没有内置工具。此外,linux perf 命令不适用于 Windows 10 的 Linux 子系统。

长答案

要访问这些计数器,您需要结合使用以下说明:

rdpmc __readpmc(见相关answer) rdmsr __readmsr wrmsr __writemsr

很遗憾,这些指令只能从内核模式调用,因此您需要与驱动程序交互。虽然编写驱动程序代码本身很容易,但让驱动程序签名并不是那么容易(特别是正如您提到的,您希望以个人身份执行此操作)。

这就是为什么我建议您研究现有项目,例如英特尔的 Open Hardware Monitor 和 pcm 项目。

打开硬件监视器

这个open-source project 是用 C# 编写的,包括二进制文件和由 OpenLibSys.org 开发的 WinRing0.sys(32 位)/WinRing0x64.sys(64 位)驱动程序的 C source-code。如果你想在你的项目中使用这个驱动,你只需要包含他们的copyright notice。

PCM

这个open-source project 是用 C++ 编写的,还包含类似驱动程序的源代码(参见 WinMSRDriver 目录),但您必须自己构建它,这样您将再次遇到签名问题。

无论如何,想提一下这个项目,因为它可能包含很多您可能感兴趣的代码。

用户模式访问

现在,一旦您加载了该驱动程序(Open Hardware Monitor 会在应用程序启动时自动提取并加载驱动程序,这非常简洁),您可以使用 Windows API 函数CreateFile / @ 开始调用这些驱动程序 IOCTL 987654332@,当然还有 CloseHandle 来自您的用户模式应用程序。

【讨论】:

即使在 VM 封装的操作系统内部——VmWare 等,它是否也能无缝工作? VM 通常不支持所有计数器,因此您可能会看到一组支持的计数器与报告的处理器系列 @user3666197 不一致 优秀。不知何故,我忽略了 LICENSE 文件。我已经使用WinRing0.sys(更准确地说,它是64 位对应的WinRing0x64.sys),所以这对我来说很简单。我更关心的是该驱动程序的模糊法律和来源可用性情况,但如果它是干净的,它就是干净的。不过,我想知道我们是否还会看到一个新的签名版本……@WouterHuysentruit @BeeOnRope 在过去的几天里,我成功地创建了应用程序 + 驱动程序,它可以读取 Windows 7 上 kabylake / skylake 上的所有性能计数器,同时对 ml64 的 masm 应用程序输出进行基准测试;它看起来像linux perf stat。我会尽快将其发布为答案 @LewisKelsey - 这太棒了,有开源它的计划吗?是否需要您将 Windows 置于开发模式才能运行驱动程序?

以上是关于我可以从 Windows 中的用户模式程序中读取 CPU 性能计数器吗?的主要内容,如果未能解决你的问题,请参考以下文章

将Sql从C#设置为单用户模式并创建管理员用户

Windows 驱动程序 - 读取 CPU 温度 - 双核

Windows系统结构

从 c# windows 窗体中的图像中读取文本

如何从 C++/Qt 中的 .exe 和 .dlls 中读取图标(在 Windows 上)?

从物理硬盘读取数据