如何在XPerf中定位空闲时间(和networkingIO时间等)?

比方说,我有一个人为的程序:

#include <Windows.h> void useless_function() { Sleep(5000); } void useful_function() { // ... do some work useless_function(); // ... do some more work } int main() { useful_function(); return 0; } 

目标 :我希望探查器告诉我useful_function()是不必要地调用useless_function() ,等待没有明显的原因。 在XPerf下,这并没有出现在我所拥有的任何图表中,因为对WaitForMultipleObjects()的调用似乎被占用了Idle.exe而不是我自己的程序。

这里是我目前运行的xperf命令行:

 xperf -on Latency -stackwalk Profile 

有任何想法吗?

(这不仅限于等待函数,上面的函数可以通过在NtWaitForMultipleObjects放置断点来解决,理想情况下可以看到堆栈样本占用大量的挂钟时间,而不是CPU时间)

我认为你要找的是在Xperf中使用Ready Thread功能的等待分析 。 它捕获每个上下文切换,并且一旦从睡眠状态唤醒(或者被阻塞的操作),就给你线程的调用栈。 在你的情况下,你会看到刚刚通话睡眠(5000)以及睡眠时间后的堆栈。

该功能有点模糊使用。 幸运的是在这里很好地描述了:

使用Xperf的等待分析进行应用程序性能故障排除

等待分析是这样做的方法。 你应该:

  • 记录CSWITCH提供者,以获得所有的上下文切换
  • 通过在您的-stackwalk参数中添加+ CSWITCH来记录上下文切换的调用栈
  • 可能在准备就绪的线程上记录调用堆栈,以获取更多关于谁准备就绪的信息(即:谁发布了互斥体或CS或信号量以及在哪里),在您的-stackwalk中添加+ READYTHREAD

然后在WPA(或xperfview,但古老的)中使用CPU Usage(Precise)来查看上下文切换,并找到TimeSinceLast在一个不应该空闲的线程上的高位。 您通常需要按照以下顺序在“CPU使用情况”(“精确”)中使用列:

  • NewProcess(您的进程正在切换)
  • NewThreadId
  • NewThreadStack
  • ReadyingProcess(谁让你的线程准备运行)
  • ReadyingThreadId(可选)
  • ReadyThreadStack(可选,需要+ ReadyThread)
  • 橙色的酒吧
  • 计数
  • TimeSinceLast(我们) – 通常按此列排序
  • 无论你想要什么其他列

有关详细信息,请参阅我的博客中的这些特定文章: – https://randomascii.wordpress.com/2014/08/19/etw-training-videos-available-now/https://randomascii.wordpress.com/2012/ 6月19日/ wpaxperf痕量的分析-重新想象/

这个“探查器”会告诉你 – 只是随机暂停几次,看看堆栈。 如果do some work需要5秒钟,并do some more work需要5秒钟,然后33%的堆栈看起来像这样

 main: calling useful_function useful_function: calling useless_function useless_function: calling Sleep 

因此,大约有33%的堆栈样本会显示这个。 任何耗费壁钟时间一小部分的代码行将大致出现在样本的一小部分上。

在其余的样品上,你会看到它做其他事情。

有自动轮廓仪,以更漂亮的方式做相同的事情,如Zoom和LTProf ,尽管他们实际上并没有展示样品。

我看了一下xperf文档,试图找出是否可以在挂钟时间获得堆栈样本,并获得行级别分辨率的百分比。 看来你必须在Windows 7或Vista。 他们只打扰功能,而不是线路,如果你有实际的大功能,是重要的。 我无法弄清楚如何获得个人样本,我认为这对于了解该项目为何花费时间非常重要。