正如标题所示,我只对获取内核模式下进程使用的CPU时钟周期感兴趣。我知道有一个名为“QueryProcessCycleTime”的API可以返回CPU时钟 进程线程使用的循环。但是这个值包括在用户模式和内核模式下花费的周期。如何才能获得在内核模式下花费的周期?我需要使用性能计数器吗?如果是的话,我应该使用哪一个?
提前感谢您的回答。
答案 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函数。这实际上返回了时钟周期的数量..但用户和内核模式一起计算。
现在,总结一下:
所以你几乎拥有所需的一切。通过一些简单的数学运算:
u_cycles = u_time * allcycles / (utime+ktime)
k_cycles = k_time * allcycles / (utime+ktime)
当然,由于四舍五入等,这将是一些近似值。
此外,这将有一个问题:您必须调用两个函数(GetTimes,QueryCycles)来获取所有信息,因此读数之间会有一点延迟,因此您的所有计算都可能会滑落一点点,因为目标进程仍在运行并烧毁时间。
如果你不能在测量中考虑到这个(小?)噪音,我认为你可以暂时暂停这个过程来绕过它:
我认为这将确保两个读数保持一致,但反过来,每个这样的读数都会影响测量过程的整体性能 - 所以“壁挂时间”之类的东西将不再可测量,除非你采取暂停时间的一些更正..
可能有更好的方法来获得单独的时钟周期,但我还没有找到它们,对不起。您可以尝试查看QueryProcessCycleTime
内部及其读取数据的来源 - 也许您很幸运,它会读取A,B并返回A + B,也许您可以查看源代码。我没有检查过。
答案 1 :(得分:1)
看看GetProcessTimes。它将为您提供进程使用的内核和用户时间。