看完Joshua Bloch的演讲《绩效焦虑》后,我读了他在演讲中建议的论文“评估 Java 分析器的准确性” http://www-plan.cs.colorado.edu/klipto/mytkowicz-pldi10.pdf。引用结论:
我们的结果令人不安,因为它们表明分析器的错误是普遍存在的——在我们的七个基准测试和两个生产 JVM 中的大多数中都发生过——而且很重要——所有四个基准测试中都出现了这种错误。
最先进的分析器会产生不正确的分析。不正确
配置文件很容易导致性能分析师花时间优化对性能影响最小的冷方法。
我们展示了一个不使用产量的概念验证分析器
采样点不会遇到上述问题
论文的结论是我们不能真正相信分析器的结果。但是,使用分析器的替代方案是什么?我们是不是应该回去凭感觉去做优化呢?
UPDATE: 讨论中似乎忽略了一点观察者效应。我们可以构建一个真正的分析器吗?观察者效应'-free?
哦,伙计,从哪里开始呢?
首先,我很惊讶这是新闻。其次,问题不在于分析器不好,而在于some分析器很糟糕。
作者构建了一个他们认为很好的模型,只是避免了他们在评估中发现的一些错误。
由于一些持续存在的原因,错误很常见关于性能分析的误解 http://archive.today/9r927.
但我们要积极一点。
如果想找到加速的机会,其实很简单:
抽样应为不相关的与程序的状态。
这意味着发生在真正随机的时间,无论程序是在 I/O(用户输入除外)中,还是在 GC 中,或者在紧密的 CPU 循环中,或者其他什么中。
抽样应读取函数调用堆栈,
以确定在采样时哪些语句是“活跃的”。
原因是每个调用点(调用函数的点)的成本百分比等于其在堆栈上的时间比例。
(注:论文完全关注自时间,忽略了大型软件中可避免函数调用的巨大影响。事实上,最初背后的原因gprof
是为了帮助找到这些电话。)
报告应显示按行百分比(不是按功能)。
如果识别出“热门”函数,人们仍然必须在其中寻找占时间的“热门”代码行。该信息是在样本中!为什么要隐藏它?
一个几乎普遍的错误(这篇论文也提到了)是过于关注计算的准确性。测量,并且精度不够location。
例如,这里有一个性能调优示例 https://stackoverflow.com/questions/926266/performance-optimization-strategies-of-last-resort/927773#927773其中发现并修复了一系列性能问题,复合加速达 43 倍。
在解决每个问题之前,不一定要准确地知道问题的大小,但要知道问题的位置。
性能调优的一个现象是,通过减少解决一个问题的时间,放大了剩余问题的百分比,因此更容易发现它们。
只要any问题被发现并解决,朝着发现并解决所有问题的目标取得进展。
不一定要按尺寸递减的顺序修复它们,但必须精确定位它们。
关于测量的统计准确性,如果调用点在堆栈上的时间百分比为 F(例如 20%),并且采用 N(例如 100)个随机时间样本,则显示调用的样本数点是二项式分布,平均值 = NF = 20,标准差 = sqrt(NF(1-F)) = sqrt(16) = 4。因此显示该点的样本百分比将为 20% +/- 4% 。
那么这准确吗?确实没有,但是问题找到了吗?恰恰。
事实上,就百分比而言,问题越大,定位它所需的样本就越少。例如,如果采集了 3 个样本,其中 2 个样本上出现了调用点,则成本很可能非常高。
(具体来说,它遵循 beta 分布。如果生成 4 个均匀的 0,1 随机数并对它们进行排序,则第 3 个的分布就是该调用点的成本分布。
其平均值为 (2+1)/(3+2) = 0.6,因此这是给定这些样本的预期节省。)
插入:您获得的加速因子受另一个分布控制,贝塔Prime https://scicomp.stackexchange.com/a/2719/1262, and its平均值为 4。因此,如果您取 3 个样本,发现其中 2 个样本存在问题,并消除该问题,平均而言,您将使程序速度提高四倍。
现在是我们程序员对分析主题的困惑的时候了。
免责声明 - 该论文未能引用我的文章:Dunlavey,“通过调用堆栈采样派生的指令级成本进行性能调整”,ACM SIGPLAN 公告 42, 8(2007 年 8 月),第 4-8 页。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)