在 Visual Studio 2017 年的分析器从 VSPX 文件导出的 XML 文件中查找 CPU 用法?

Finding CPU usage in the XML files exported by Visual Studio 2017's profiler from a VSPX file?

我需要解析 Visual Studio 的性能分析器生成的 XML 文件,并获取有关 CPU 我程序中每个函数的用法的信息(类似于 Visual Studio 显示在诊断工具和性能分析器中)。

我尝试查看所有可以使用该工具生成的 XML 文件(call tree summaryfunction summaryprocess summary 等),但我没有似乎找不到有关 CPU 用法的信息。

我应该导出哪些 XML 视图来获取此信息?另外,我在哪里可以找到 CPU 用法? InclSamplesExclSamples 是什么?这是我的函数摘要 XML:

中的一个示例
<Function FunctionName="MatrixMultiply.Program.FunctionName" InclSamples="1,444" ExclSamples="881" InclSamplesPercent="97.30" ExclSamplesPercent="59.37" />

为了正确生成 XML 文件,您必须选择一个目标并选中 Performance Profiler (Alt + F2) 中的分析 CPU Usage,这在 Debug > Performance Profiler 菜单中可用落下。此 window 是 diagsession window,它要求您选择所需的性能报告并开始分析。

- CPU Usage
- Memory Usage
- GPU Usage

将报告导出到 VSPX 文件后,VS2017 允许您将此二进制文件导出到可读的 CSVs/XML 文件中。在出现的菜单中,您可以选择您喜欢的不同报告。探查器可以为您生成的一些报告是:

  • 来电者被叫者摘要
  • 调用树摘要
  • 函数总结
  • Header 摘要
  • IP 摘要
  • 线路摘要
  • 分数汇总
  • 模块摘要
  • 过程总结
  • 处理线程摘要
  • 线程摘要

您似乎对 CallTreeSummary 最感兴趣,导出的 XML 文件的名称为 <reportname>_CallTreeSummary.xml,其中包含 <PerformanceReport>,其中包含 <CallTreeSummary>

CallTreeSummary 中的每个 CallTree 调用都包含 functionNameInclSamplesExclSamples 及其各自的百分比。 这是一个例子:

示例C++代码如下(内存泄漏示例):

int main() {
    while (true) {
        int *p = new int;
    }
    return 0;
}

部分CallTree显示如下:

<CallTree Level="8" FunctionName="operator new" InclSamples="20,560" ExclSamples="78" InclSamplesPercent="97.46" ExclSamplesPercent="0.37" ModuleName="Sample.exe" />
<CallTree Level="9" FunctionName="[ucrtbased.dll]" InclSamples="20,482" ExclSamples="55" InclSamplesPercent="97.09" ExclSamplesPercent="0.26" ModuleName="ucrtbased.dll" />
<CallTree Level="10" FunctionName="[ucrtbased.dll]" InclSamples="20,427" ExclSamples="83" InclSamplesPercent="96.83" ExclSamplesPercent="0.39" ModuleName="ucrtbased.dll" />
<CallTree Level="11" FunctionName="[ucrtbased.dll]" InclSamples="20,344" ExclSamples="177" InclSamplesPercent="96.44" ExclSamplesPercent="0.84" ModuleName="ucrtbased.dll" />
<CallTree Level="12" FunctionName="[ucrtbased.dll]" InclSamples="20,119" ExclSamples="2,092" InclSamplesPercent="95.37" ExclSamplesPercent="9.92" ModuleName="ucrtbased.dll" />

InclSamples 表示执行函数和调用的任何相关函数所花费的滴答总数。 ExclSamples 表示执行 函数所花费的滴答总数。

作为说明性示例,请考虑以下示例:

int bar() {
    return 1;
}

int foo() {
    return bar();
}

int main() {
    int x = foo();
    return 0;
}

示例执行可以显示以下数据:

<FunctionName="main" InclSamples="100" ExclSamples="10" InclSamplesPercent="100.00" .../>
<FunctionName="foo" InclSamples="90" ExclSamples="40" InclSamplesPercent="90.00".../>
<FunctionName="bar" InclSamples="50" ExclSamples="50" InclSamplesPercent="50.00" .../>

解释如下:

  • 运行 main() 函数总共需要 100 CPU 个滴答,但只有 10 个滴答导致执行此函数,给我们留下 90 个滴答在从 main()
  • 调用的其他函数中使用
  • 运行 foo() 函数需要 90 CPU 个滴答(因为它包括 foo() + bar() 的 运行 时间,但不包括 foo()需要 40 个刻度。
  • bar() 函数需要 50 个滴答到 运行。

使用上面的推理,您可以推理上面提供的 CallTree 示例。关联的 InclSamplesPercent 是 CPU 占整个任务 运行 所用时间的百分比。例如从上面的示例中我们可以说 CPU 的 100%main() 函数使用,但 90%foo() 函数占用,并且 50% by bar() 函数有效地使 ExclSamplesPercent by foo()90 - 50 = 40.00%ExclSamplesPercent by main()100 - 90 = 10%