如何在Windows上以内核模式获取进程使用的CPU时钟周期?

时间:2014-02-24 12:13:38

标签: c++ windows cpu-cycles

正如标题所示,我只对获取内核模式下进程使用的CPU时钟周期感兴趣。我知道有一个名为“QueryProcessCycleTime”的API可以返回CPU时钟 进程线程使用的循环。但是这个值包括在用户模式和内核模式下花费的周期。如何才能获得在内核模式下花费的周期?我需要使用性能计数器吗?如果是的话,我应该使用哪一个?

提前感谢您的回答。

2 个答案:

答案 0 :(得分:2)

我刚刚发现了一篇有趣的文章,几乎描述了你的要求。它在MSDN Internals上。

他们在那里写道,如果您使用的是C#或C ++ / CLI,您可以轻松地从System.Diagnostic.Process类的实例获取该信息,指向正确的PID。但它会从TimeSpan给你一个PrivilegedProcessorTime,所以“漂亮的时间”而不是“周期”。

但是,他们还指出,所有.Net代码实际上都是非托管API的瘦包装器,因此您应该能够轻松地从本机C ++中获取它。他们是ILDASM的那个班,以显示它所称的,但图像丢失了。我刚刚做了同样的事情,它使用GetProcessTimes

中的kernel32.dll

再次,MSDN'ing it - 它返回LPFILETIME个结构。所以,'漂亮的时间',而不是'周期',再次。

此方法的说明指出,如果要获得时钟周期,则应使用QueryProcessCycleTime函数。这实际上返回了时钟周期的数量..但用户和内核模式一起计算。

现在,总结一下:

  • 您可以阅读userTIME
  • 您可以阅读kernelTIME
  • 你可以阅读(用户+内核)CYCLES

所以你几乎拥有所需的一切。通过一些简单的数学运算:

u_cycles = u_time * allcycles / (utime+ktime)
k_cycles = k_time * allcycles / (utime+ktime)

当然,由于四舍五入等,这将是一些近似值。

此外,这将有一个问题:您必须调用两个函数(GetTimes,QueryCycles)来获取所有信息,因此读数之间会有一点延迟,因此您的所有计算都可能会滑落一点点,因为目标进程仍在运行并烧毁时间。

如果你不能在测量中考虑到这个(小?)噪音,我认为你可以暂时暂停这个过程来绕过它:

  • 暂停目标
  • 等一下,确保它被暂停
  • 阅读第一个统计数据
  • 读取第二个统计数据
  • 然后恢复流程并计算值

我认为这将确保两个读数保持一致,但反过来,每个这样的读数都会影响测量过程的整体性能 - 所以“壁挂时间”之类的东西将不再可测量,除非你采取暂停时间的一些更正..

可能有更好的方法来获得单独的时钟周期,但我还没有找到它们,对不起。您可以尝试查看QueryProcessCycleTime内部及其读取数据的来源 - 也许您很幸运,它会读取A,B并返回A + B,也许您可​​以查看源代码。我没有检查过。

答案 1 :(得分:1)

看看GetProcessTimes。它将为您提供进程使用的内核和用户时间。