功能分析困境 - 的Visual Studio 2010旗舰版功能分析困境 - 的Visual St

2019-05-12 05:57发布

我试图分析我的应用程序之前和之后重构监控功能的影响。 我已经完成我的应用程序的分析,说完看着我注意到摘要热路径列表中没有提到任何的用我的功能,仅提及了功能最多Application.Run()

我是相当新的剖析,并想知道我怎么能获取有关经由展示的热路径的更多信息MSDN文档 ;

MSDN实施例:

我的结果:

我注意到在输出窗口中加载符号时有很多关于失败的消息,他们几个都低于;

Failed to load symbols for C:\Windows\system32\USP10.dll.  
Failed to load symbols for C:\Windows\system32\CRYPTSP.dll.
Failed to load symbols for (Omitted)\WindowsFormsApplication1\bin\Debug\System.Data.SQLite.dll.
Failed to load symbols for C:\Windows\system32\GDI32.dll.  
Failed to load symbols for C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.7601.17514_none_41e6975e2bd6f2b2\comctl32.dll.
Failed to load symbols for C:\Windows\system32\msvcrt.dll. 
Failed to load symbols for C:\Windows\Microsoft.NET\Framework\v4.0.30319\nlssorting.dll.
Failed to load symbols for C:\Windows\Microsoft.Net\assembly\GAC_32\System.Data\v4.0_4.0.0.0__b77a5c561934e089\System.Data.dll.  Failed to load symbols for
C:\Windows\Microsoft.Net\assembly\GAC_32\System.Transactions\v4.0_4.0.0.0__b77a5c561934e089\System.Transactions.dll.
Unable to open file to serialize symbols: Error VSP1737: File could not be opened due to sharing violation: - D:\(Omitted)\WindowsFormsApplication1110402.vsp

(格式化使用代码工具,所以它是可读的)

感谢您的任何指针。

Answer 1:

在摘要视图中所示的“热路径”是基于包含样本(从功能样品并且也从功能样品由函数调用)和专属样品(仅从函数的样品)的数量最昂贵的呼叫路径。 “样品”仅仅是事实的功能是在堆栈的顶部,当分析器的驱动程序捕获的堆栈(这发生在非常小的时间间隔)。 因此,更多的样本函数具有,它越正在执行。

默认情况下,抽样分析,启动了一个名为“ 仅我的代码 ”功能,堆栈是从非用户模块来对隐藏功能(它会显示1非用户功能的深度,如果叫用户的功能;在你的情况Application.Run )。 从模块来而不加载符号或从已知可从微软模块的功能将被排除在外。 在总结查看您的“热路径”表示最昂贵的堆栈没有从什么探查认为是你的代码(比其他任何Main )。 从MSDN的例子显示了因为更多的功能PeopleTrax.*PeopleNS.*功能从“用户代码”来。 “仅我的代码”可以通过点击摘要视图“显示全部代码”链接被关闭,但我不建议这样做在这里。

看看在“ 功能做最个人工作 ”的摘要视图。 这显示有最高的独家样本数,因此基于该分析方案的功能,最昂贵的功能调用。 您应该看到您更多的功能(或功能由你的函数调用)在这里。 此外,“ 功能 ”和“ 调用树 ”视图可能会显示你更多的细节(有在报告顶部的下拉列表选择当前视图)。

至于你的符号警告,那些最有望,因为他们是微软的模块(不包括System.Data.SQLite.dll)。 虽然你不需要为这些模块的符号正确地分析您的报告,如果你在“工具 - >选项 - >调试 - >符号”选中“Microsoft符号服务器”并重新打开报告,这些模块的符号应加载。 请注意,它会需要更长的时间来打开报表第一次,因为符号需要下载并缓存。

关于失败序列化符号到报告文件中的其他警告是不能够被写入,因为它是由别的东西,防止写入打开文件的结果。 符号序列化是一个优化,允许探查,直接从下一个分析报告文件加载符号信息。 如果没有符号序列,分析只需要执行的工作相同数量的报表时首次打开时间。

最后,你还可以尝试在你的分析会话设置仪器 ,而不是抽样。 仪表修改您指定要捕捉每一个函数调用(注意,这可能会导致一个非常非常大的.VSP文件)数据模块。 仪器是理想的聚焦于特定的代码段的定时,而采样是理想的一般低开销分析数据集合。



Answer 2:

你介意太多,如果我谈点纹,什么可行,什么不可行?

让我们做了一个人工程序,其中一些人的陈述是这样做可以优化掉工作 - 也就是说,它们是不是真的有必要。 他们是“瓶颈”。

子程序foo运行CPU结合的循环,需要一秒钟。 此外,假设子程序调用和返回指令采取微不足道或零时间,相比于一切。

子程序barfoo 10倍,但这些时间9是不必要的,你不提前知道,不能告诉,直到你将注意力转向那里。

子程序ABC ,..., J是10子程序,并且它们每一个呼叫bar一次。

顶层例程main每个呼叫A通过J一次。

所以总的呼叫树是这个样子:

main
  A
    bar
      foo
      foo
      ... total 10 times for 10 seconds
  B
    bar
      foo
      foo
      ...
  ...
  J
    ...
(finished)

多久都需要? 100秒,效果显着。

现在,让我们来看看剖析策略。 堆的样品(如说1000个样本)取以均匀的间隔。

  1. 有没有自我的时间? 是。 foo采取的自我时间的100%。 这是一个真正的“热点”。 这是否帮助你找到瓶颈? 不是。因为它不是foo

  2. 什么是热的路径? 好了,堆样品是这样的:

    主 - > A - >巴 - > FOO(100个样本,或10%)
    主 - >乙 - >巴 - > FOO(100个样本,或10%)
    ...
    主 - >的J - >巴 - > FOO(100个样本,或10%)

有10条热门路径,它们不会显得足够大,以获得你多少加速。

如果你碰巧猜,如果描述器,你可以把bar的呼叫树的“根”。 然后你会看到这一点:

bar -> foo (1000 samples, or 100%)

然后,你就会知道, foobar各自为100%的时间独立负责,因此是地方寻找优化。 你看看foo ,当然你知道的问题是不存在的。 然后,你看看bar ,您将看到10个电话来foo ,你看到他们的9是不必要的。 问题解决了。

如果未发生GUESS,而是探查只是表明你包含每个常规样品的百分比,你会看到这一点:

main 100%
bar  100%
foo  100%
A    10%
B    10%
...
J    10%

这告诉你看看mainbar ,和foo 。 您可以看到mainfoo是无辜的。 你看看那里barfoo ,你看到的问题,所以它的解决。

这是更清楚,如果除了向您展示的功能,你可以在提供的功能被称为线。 这样,你可以不管功能多么大的源文本中的条款发现问题。

现在,让我们改变foo ,以便它sleep(oneSecond)而不会是CPU的约束。 这是如何变化的东西呢?

它的意思是它仍然由挂钟需要100秒,而CPU时间为零。 采样的CPU,只有采样器将显示什么

所以,现在你被告知要尽量仪器,而不是抽样。 在所有它会告诉你的东西包含的,它也告诉你上面显示的百分比,所以在这种情况下,你会发现这个问题,假设bar是不是很大。 (有可能是原因写的小功能,但应满足分析器是其中之一?)

其实,主要的一点毛病取样是,它不能在品尝sleep (或I / O或其他阻断),并且它不会显示你的代码行百分比,只有百分之功能。

顺便说一句,1000个样本为您提供了很好的精确的前瞻性百分比。 假设你花了较少的样本。 有多少你真的需要找到瓶颈? 那么,既然瓶颈上的时间堆90%,​​如果你只用了10个样本,这将是对他们的9,所以你仍然可以看到它。 如果你甚至采取少3个样品的概率会出现在两个或更多的人是97.2%。**

高采样率的方式高估了,当你的目标是找到瓶颈。

不管怎么说,这就是为什么我靠随机暂停 。

**我是怎么百分之97.2? 把它看成是掷硬币的3倍,一个非常不公平的硬币,其中“1”是指在看到瓶颈。 有8种可能:

       #1s  probabality
0 0 0  0    0.1^3 * 0.9^0 = 0.001
0 0 1  1    0.1^2 * 0.9^1 = 0.009
0 1 0  1    0.1^2 * 0.9^1 = 0.009
0 1 1  2    0.1^1 * 0.9^2 = 0.081
1 0 0  1    0.1^2 * 0.9^1 = 0.009
1 0 1  2    0.1^1 * 0.9^2 = 0.081
1 1 0  2    0.1^1 * 0.9^2 = 0.081
1 1 1  3    0.1^0 * 0.9^3 = 0.729

所以看到它2〜3次的概率为0.081 * 3 + 0.729 = 0.972



文章来源: Function profiling woes - Visual Studio 2010 Ultimate