我在分析本机代码方面的大部分经验都是在GPU上而不是在CPU上,但我将来会看到一些CPU分析......
现在,我刚刚阅读了这篇博文:
How profilers lie: The case of gprof and KCacheGrind
关于分析者如何衡量以及他们向您展示的内容,如果您有兴趣辨别不同的呼叫路径和在其中花费的时间,那么这可能不是您所期望的。
我的问题是:今天(5年后)仍然如此吗?也就是说,采样分析器(即那些不会严重降低执行速度的分析器)仍然表现得像gprof那样(或没有--separate-callers=N
的callgrind)?或者,现在分析器通常在采样时记录整个调用堆栈?
答案 0 :(得分:3)
不,许多现代抽样分析仪都没有出现有关gprof的问题。
事实上,即使写了这篇文章,具体问题实际上更像是gprof
使用混合的仪器和采样然后尝试重建假设的调用的方式的怪癖基于有限的呼叫者/被呼叫者信息的图表,并将其与采样的定时信息相结合。
现代抽样分析器,例如perf
,VTune,以及各种语言特定的分析器,不能编译为本机代码的语言,可以捕获每个样本的完整调用堆栈,这提供了与那个问题。或者,您可以在不收集调用堆栈的情况下进行采样(这大大降低了采样成本),然后在没有任何仍然准确的调用者/被调用者信息的情况下显示信息。
即使在过去,这一点基本上都是正确的,所以我认为抽样分析器从来没有像小组一样真正展现出这个问题。
当然,分析师仍然可以通过各种方式撒谎。例如,将结果精确到指令级别是一个非常棘手的问题,考虑到现代CPU一次就有100个指令,可能跨越许多函数,以及复杂的性能模型,其中指令可能具有非常不同的上下文成本。到它们的标称延迟和吞吐量值。即使是那些棘手的问题也可以通过“硬件辅助”来帮助,例如最近的x86芯片PEBS support以及后来的相关功能,这些功能可以帮助您以更偏向的方式精确定位指令。
答案 1 :(得分:2)
关于gprof,是的,今天仍然如此。这是设计上的,以保持分析开销很小。从最新documentation:
开始调用图中的一些数字是估计值 - 例如, 子项时间值以及调用者和子例程中的所有时间数字 线。
配置文件中没有关于这些测量的直接信息 数据本身。相反,gprof通过做出假设来估计它们 关于你的计划可能会或可能不是真的。
假设是每次通话花费的平均时间 函数foo与谁调用foo无关。如果foo使用5 所有的秒数,以及对foo的2/5调用来自a,然后是foo 通过假设,给孩子的时间贡献2秒。
关于KCacheGrind,自撰写文章以来,几乎没有变化。您可以查看change log,看看最新版本是否已于2013年4月5日发布,其中包含不相关的更改。您还可以参考Josef Weidendorfer在文章(Josef是KCacheGrind的author)下的评论。
答案 2 :(得分:0)
如果您注意到,我对您引用的帖子提供了一些评论,但不仅仅是个人资料管理器会向您提供不良信息,而且人们会欺骗自己实际上的表现。
你的目标是什么?是否A)找出如何尽可能快地制作程序?或者是B)测量各种功能所需的时间,希望这会导致A? (提示 - 它没有。)Here's a detailed list of the issues.
举例说明:例如,你可以在某个地方调用一个看起来很无辜的小函数,恰好调用九码系统代码,包括读取.dll来提取字符串资源以使其国际化。这可能占据挂钟时间的50%,因此可以在挂钟时间的50%上堆叠。一个" CPU-profiler"给你看?不,因为几乎所有50%的人都在进行I / O.您是否需要许多堆栈样本才能知道它需要多少时间才能得到3位小数?当然不是。如果你只有10个样品,那就是5个样品,给予或采取。一旦你知道那个小小的例程是一个大问题,这是否意味着你因为其他人写的而失去了运气?如果你知道它正在查找字符串怎么办?它是否真的需要国际化,以至于你愿意为此缓慢付出两倍的代价?当你真正的问题是理解定性需要时间时,你是否看到无用的测量结果?
我可以继续这样的例子......