我有一个 c + + 应用程序,我是在优化的过程中。什么方法或工具可用于查明完全是我的代码在其中运行缓慢?

2008-12-17 20:29:24
问题评论:

如果您将提供更多的数据,有关开发堆栈可能获得更好的答案。从英特尔和太阳的探查器,但您必须使用其编译器。这是一个选项?

它已回答下面的链接︰ stackoverflow.com/questions/2497211/...

大多数回答都是code探查器。但是,优先级反转缓存锯齿、 资源争夺、 等都可以在优化和性能的因素。我认为人阅读到我效率低下的代码的信息。常见问题解答对象正在引用此线程。

这应该不会关闭。没有人是否曾经 reopen 问题?

@mikenelson︰ 它被称为"没有建设性",这似乎很奇怪。我不知道有关关闭,但就删除而言,有数以百计的人,除了我,看到这里的值。

回答:

如果您的目标是使用探查器,使用一个建议。

但是,如果你急于和正在 subjectively 慢时,可以手动中断您的程序在调试器下,是非常简便地发现性能问题。

只需进行几次,暂停,每次查看调用堆栈。如果有一些代码,浪费时间,20%、 50%或任何,一定百分比的是,您将作用于每个示例中捕获它的可能性。这是大致您将看到它的样本的百分比。没有必要的猜测。如果您没有猜测问题是什么,这将证明或期望它。

可能有多个不同规模的性能问题。如果您清除其中的任意一个,剩余的将采用较大的比例,并更容易发现,在后续处理过程。这种放大效果,当复杂了过多的问题,可能会导致真正大规模加速因素。

警告︰ 程序员往往是不解这种方法的除非他们使用的是它本身。他们会说,探查器为您提供此信息,但它是唯一一个真正的是否采样整个调用堆栈,然后让您检查一组随机样本。(摘要是其中见解都将丢失。调用关系图不为您提供相同的信息因为

  1. 他们没有指令级别汇总和
  2. 它们给混乱摘要存在递归。

他们还会说它只有玩具程序时,实际上它适用于任何程序中,并且它看起来更适用于较大的程序,因为它们往往会有更多的问题来查找。他们会说它有时发现的事情,不是问题,但这只是如果您看到的内容之后如果您看到多个样本的问题,它是真实的。

P.S.这也可以在多线程程序如果还有时间,收集调用堆栈样本点的线程池的方法如在 Java 中,没有。

P.P.S 为粗糙的普遍性、 多层的抽象中有您的软件,了解越多,您在查找的是性能问题 (并有机会获得加速) 的原因。

添加︰ 它可能不太明显,但堆栈采样技术效果都很好地存在递归。其原因是通过样本包含它,而不考虑它在一个样本中可能发生的次数的分数近似,将由指令删除保存的时间。

我经常听是另一个异议:"它将停止地方随机的并且它会错过真正的问题"。这来自于具有前期概念的真正的问题是什么。性能问题的一个关键属性是他们 defy 的期望。采样告诉您一些问题,且您的第一反应是表示怀疑。这是自然的但可以确保,如果找到了,它是真实的问题,反之亦然。

增加︰ 让我制作的贝叶斯原理的说明。假设I一些指令 (调用或其他方式) 这是调用堆栈上的时间有些分数f (并且,这样的成本,很多)。为简单起见,假设我们不知道哪种f ,但假定它为 0.1、 0.2、 0.3,为单位...0.9 1.0,,以前每个这些可能性的概率是 0.1,因此所有这些成本都同样是一个 priori 可能。

然后假设我们只需 2 堆栈样本,并且我们看到在这两个示例,指定观测指令I o=2/2这为我们提供了新估计的频率f I,据此︰

Prior                                    
P(f=x) x  P(o=2/2|f=x) P(o=2/2&&f=x)  P(o=2/2&&f >= x)  P(f >= x)

0.1    1     1             0.1          0.1            0.25974026
0.1    0.9   0.81          0.081        0.181          0.47012987
0.1    0.8   0.64          0.064        0.245          0.636363636
0.1    0.7   0.49          0.049        0.294          0.763636364
0.1    0.6   0.36          0.036        0.33           0.857142857
0.1    0.5   0.25          0.025        0.355          0.922077922
0.1    0.4   0.16          0.016        0.371          0.963636364
0.1    0.3   0.09          0.009        0.38           0.987012987
0.1    0.2   0.04          0.004        0.384          0.997402597
0.1    0.1   0.01          0.001        0.385          1

                  P(o=2/2) 0.385                

最后一列说,例如的概率, f > = 0.5 是 92%,最多来自事先假定的 60%。

假设之前的假设是不同的。假设我们假定 P(f=0.1) 是.991 (几乎可以肯定),和所有其他的可能性都几乎不可能 (0.001)。换句话说,我们以前肯定是I的便宜。然后,我们得到︰

Prior                                    
P(f=x) x  P(o=2/2|f=x) P(o=2/2&& f=x)  P(o=2/2&&f >= x)  P(f >= x)

0.001  1    1              0.001        0.001          0.072727273
0.001  0.9  0.81           0.00081      0.00181        0.131636364
0.001  0.8  0.64           0.00064      0.00245        0.178181818
0.001  0.7  0.49           0.00049      0.00294        0.213818182
0.001  0.6  0.36           0.00036      0.0033         0.24
0.001  0.5  0.25           0.00025      0.00355        0.258181818
0.001  0.4  0.16           0.00016      0.00371        0.269818182
0.001  0.3  0.09           0.00009      0.0038         0.276363636
0.001  0.2  0.04           0.00004      0.00384        0.279272727
0.991  0.1  0.01           0.00991      0.01375        1

                  P(o=2/2) 0.01375                

现在,它说 P (f > = 0.5) 为 26%,最多事先假定的 0.6%。因此 Bayes 使我们更新我们的I的可能成本的估计。如果数据量很小,它不会告诉我们准确成本那是什么,只是大得足以值得修复。

另一种方式看它尚未调用规则的连续如果翻转硬币 2 倍,而且它会人头两次,告诉什么内容,则有关硬币的可能的权重?尊敬的方式来回答是说它是一个 Beta 分布,用平均值 (数点击 + 1)/(数次尝试 + 2) = (2+1)/(2+2) = 75%。

(关键是,我们看到I不止一次。如果我们只看一次,它并没有告诉我们很多除f > 0。)

因此,即使很小的样本数可以告诉我们很多说明它所看到的成本。(和它将看到这些频率,平均,其成本成正比。如果n示例将执行,并且f是成本,然后I会出现在nf+/-sqrt(nf(1-f))的示例。示例中, n=10f=0.3,也就是说3+/-1.4样本。)

这基本上是廉价的取样探查器,这一点很不错,但运行太小样本大小将可能使您可以完全虚假的结果的风险。

@Crash︰ 我不会:-) 争论的"廉价"部分它是如此,统计测量精度要求的许多示例,但两个相互冲突的目标的量化指标和问题位置。我在 focussing 上后,您需要的位置,不精确的测量精度。例如,可以有中, 端堆栈,一个函数调用 a ();占 50%的时间,但它可以被另一个大的函数 B,以及许多其他调用 a () 不是成本高昂。精确的汇总函数的时间可以是一个线索,但每个其他堆栈示例将查明问题。

...世界似乎认为调用-图,以调用的计数和/或平均计时,批注是足够好。不是这样。和悲伤的部分是,对于那些示例调用堆栈、 最有用的信息面前,但他们将它扔掉,在"统计信息"的兴趣。

我并不想同意您的方法。很显然我非常严重依赖堆栈审核取样探查器。我只指出有一些工具,做到以自动化的方式现在,当您感到点之后的函数获得 15%到 25%,且需要驳倒它从 1.2%到 0.6%,这具有重要意义。

感谢这么多的这一思想。我只是使用而且我能够识别和改善某些严重瓶颈光年比我试过的任何其他方法更快。我加快执行的 60 倍。在调试的代码,我曾考虑添加的所有计时的思想,我感到震惊。

您可以使用带有以下选项的Valgrind

valgrind --tool=callgrind ./(Your binary)

它将生成一个名为callgrind.out.x的文件。然后可以使用kcachegrind工具来读取该文件。它将为您提供的图形分析的结果类似的行成本多少事情。

valgrind 很好,但请注意它将使您的程序相当慢

签出还Gprof2Dot的令人惊叹的另一种方法可以直观地显示输出。./gprof2dot.py -f callgrind callgrind.out.x | dot -Tsvg -o output.svg

@neves 是 Valgrind 只是不是在进行分析的"gstreamer"和"opencv"应用程序实时速度方面很有用的。

...stackoverflow.com/questions/375913/是速度问题的部分解决方案。

我假定您正在使用 GCC。标准的解决方案是使用gprof的配置文件.

一定要添加-pg为评测之前编译︰

cc -o myprog myprog.c utils.c -g -pg

我还没有尝试过它,但我以前听说google perftools件好事情。这一点非常值得一试。

相关的问题这里.

几个如果gprof不会为您执行作业其他流行用语︰ Valgrind,英特尔VTune,Sun DTrace.

我同意该 gprof 是目前的标准。说明一点,不过,Valgrind 用于配置文件内存泄漏和程序,其他与内存相关方面不为速度优化。

比尔,vaglrind 套件中您可以找到 callgrind 和 massif。两者都是对配置文件的应用程序很有用

@Bill-the-Lizard︰ 对gprof的某些意见︰ stackoverflow.com/questions/1777556/alternatives-to-gprof/...

请参阅下面, stackoverflow.com/a/6540100/823636我 gprof 注意事项

gprof-pg 只是近似的调用堆栈的性能分析。它插入 mcount 的调用,以跟踪哪些函数调用的其他函数。它使用标准时间基于采样,呃,时间。它然后 apportions 采样回 foo () 的调用 numberr 到 proprtion 中的调用方函数 foo () 的时间。因此它并不区分调用的开销不同。

较新的内核 (如最新 Ubuntu 内核) 附带新的性能工具 (apt-get install linux-tools) 也称为perf_events.

这些超timechart以及来自经典取样探查器 (手册页!

重要的是,这些工具可以是系统分析,而不仅仅是流程分析,即它们可以显示线程、 进程和内核之间的交互,让您了解的计划和进程之间的 I/O 依赖项。

Alt text

很好的工具 !仍有我来获取用于启动一个典型的"蝴蝶"视图的"主-> func1-> fun2"样式?我似乎无法找到解决办法...perf report似乎给我与调用父项的函数名。.(因此它是某种程度的竖的蝴蝶视图)

将性能显示 timechart 的线程活动;与添加 CPU 的数字信息?我想看到的时间和每个 CPU 上运行的线程。

@kizzx2-您可以使用gprof2dotperf script非常好的工具 !

OProfile最好,因为它比Gprof同时分析多个程序容易得多。您还可以运行它在您的发布版本 (如果有符号),而无需构建一个特殊的分析生成。

如果您不关心花极大的性能问题 (50 倍), Valgrind (Cachegrind) 是很好。

+ 1,oprofile 太棒了,看一看整个系统,并分析在内核空间中的代码

Oprofile 也似乎比 gprof 编码中比许多其他工具集的功能更好地工作。

oprofile 总是被描述为内核事件探查器或系统配置文件中。我从未使用过它这种情况。我设置 oprofile 要作为筛选依据的可执行文件目前正在研究,并忽略内核和系统的其余部分。很诚实地发现性能问题的最佳办法。作为奖金 OProfile 并测量统计非原始的 CPU 使用率。我个人最喜欢是 L2_cache 失误,适合在线程代码中查找缓存失效。

oprofile 需求过多设置,是不可靠,我浪费了 2 个小时,只是为了尝试一下。当我无法获得结果时,结果已不过好。

如果您只分析一个可执行文件,请使用"operf"命令来运行它。这使得它非常简单,并不需要安装程序。

请输入您的翻译

What can I use to profile C++ code in Linux? [closed]

确认取消