哪个是最可靠的性能分析工具gprof或k​​cachegrind?

| 使用
gprof
kcachegrind
对某些C ++数字运算代码进行性能分析,可以得出对执行时间影响最大​​的函数的相似结果(取决于输入的50-80%),但是对于介于10%至30%之间的函数,这两种工具都可以得出不同的结果。这是否意味着其中之一不可靠?您在这里做什么?     
已邀请:
        gprof实际上是非常原始的。这就是它的作用。 1)它以恒定的速率对程序计数器进行采样,并记录每个功能(独占时间)中有多少个采样。 2)计算任何函数A调用任何函数B的次数。 从中可以找出每个函数总共被调用了多少次,以及它的平均排他时间是多少。 为了获得每个函数的平均包含时间,它在调用图中向上传播专用时间。 如果您希望它具有某种准确性,则应注意一些问题。 首先,它仅计算CPU的处理时间,这意味着它对I / O或其他系统调用不了解。 其次,递归混淆了它。 第三,非常怀疑函数是否始终遵守平均运行时间的前提,无论何时调用它们或由谁调用它们。 第四,功能(及其调用图)是您需要了解的概念,而不是代码行,只是一种流行的假设,仅此而已。 第五,测量精度甚至与发现“瓶颈”有关的观念也只是一个普遍的假设,仅此而已。 Callgrind可以在线路级别上工作-很好。不幸的是,它还有其他问题。 如果您的目标是找到“瓶颈”(而不是进行常规测量),则应查看按时钟报告百分比的壁钟时间堆栈采样器,例如Zoom。 原因很简单,但可能不熟悉。 假设您有一个程序,其中有很多函数互相调用,总共需要10秒钟。另外,还有一个采样器,不仅对程序计数器进行采样,而且对整个调用堆栈进行采样,并且始终以恒定速率(例如每秒100次)进行采样。 (暂时忽略其他进程。) 因此,最后有1000个调用堆栈样本。 选择出现在其中一个以上的任何代码L。 假设您可以通过避免,删除或将其传递给真正快速的处理器来以某种方式优化该行。 这些样本会怎样? 由于该行代码L现在(基本上)根本不需要时间,因此没有样本可以命中它,因此这些样本将消失,从而减少了样本总数,从而减少了总时间! 实际上,总时间将减少堆栈上的时间L,这大约是包含该时间的样本的一部分。 我不想过于统计,但是许多人认为您需要大量样本,因为他们认为测量的准确性很重要。 并不是这样,如果您这样做的原因是要找出要解决的问题以加快速度。 重点是找到要解决的问题,而不是衡量问题。 L行在堆栈上大约F的时间,对吗? 因此,每个样本都有击中它的概率F,对吗?就像掷硬币一样。 有一个这样的理论,称为继承规则。 它说(在简化但通用的假设下),如果您将硬币翻转N次并看到“正面” S次,则可以将硬币F的公平性估计为(平均)ѭ2。 因此,如果您少取三个样本,并且在两个样本上看到L,您知道F是什么吗?当然不是。 但您确实知道平均为(2 + 1)/(3 + 2)或60%。 这样,您可以“优化掉”第L行来平均节省多少时间。 并且,当然,堆栈样本向您显示了L行(“瓶颈” **)的确切位置。 您没有将其测量到小数点后两位或三位真的很重要吗? 顺便说一句,它不受上述所有其他问题的影响。 **我总是在“瓶颈”周围加引号,因为使大多数软件变慢的原因与瓶颈无关。 更好的比喻是“流失”-只是不必要地浪费时间。     
gprof
's的计时数据是统计信息(有关分析文档的详细信息,请阅读此信息)。 另一方面,
KCacheGrind
使用
valgrind
来实际解释所有代码。 因此,如果由
valgrind
建模的CPU与您的真实CPU接近,则
KCacheGrind
可以“更准确”(以更多开销为代价)。 选择哪种方法还取决于您可以处理的间接费用类型。以我的经验,
gprof
减少了运行时开销(即执行时间),但更具侵入性(i9ѭ将代码添加到每个函数中)。因此,根据情况,在另一个上比较合适。 对于“更好”的“ 0”数据,请运行更长的代码(并且可以使用尽可能多的测试数据)。您拥有的越多,统计结果就越好。     

要回复问题请先登录注册