用Callgrind分析CFD代码


16

我正在使用Valgrind + Callgrind对我编写的求解器进行分析。如Valgrind用户手册所述,我已经使用编译器的调试选项编译了代码:

“没有调试信息,最好的Valgrind工具将能够做的就是猜测特定代码段属于哪个功能,这将使错误消息和性能分析输出几乎无用。使用-g,您将获得直接指向相关的源代码行。”

Valgrind手册

使用调试选项进行编译时,代码的运行速度要慢得多。即使使用调试标志进行编译,即使在很小的情况下,CFD代码也会变得非常缓慢。Valgrind使其速度降低40倍(请参见手册1)。

  1. 您使用什么工具进行代码性能分析(性能分析,而不是基准测试)?

  2. 您允许代码运行多长时间(统计数据:多少个时间步长)?

  3. 大小有多大(如果大小写适合高速缓存,则求解器的速度要快几个数量级,但是我会错过与内存相关的过程)?


3
您可以同时启用调试符号和优化功能来编译代码。尽管如此,通过valgrind进行40倍(模拟所有内存访问)并非没有道理。
阿隆·艾玛迪亚

谢谢,这也是我读过的...我想了解的是有关日常分析经验的信息(最好使用valgrind):等待报告的正常时间是多少,等待多少次迭代我需要计数,我可以排除什么...等等...
tmaric 2012年

您的问题也很广泛。我建议您将问题简化为Q2.1和Q2.2,因为Q1是一个完全不同的问题(很高兴您单独提出该问题,这是一个很好的问题,但是将其表述为“您会使用哪种工具用来解决问题X”,其中X的描述很清楚!),而Q2本身太笼统了。
阿隆·艾玛迪亚

你也可以编辑命名callgrindcachegrindmassif。许多人仅将Valgrind与默认工具(memcheck)关联。作为基于仿真(而不是基于中断)的分析系统,您无需运行很长时间。
杰德·布朗

@Aron&Jed:感谢您的提示,我已经编辑了问题。:)
tmaric 2012年

Answers:


11

Q1:您使用什么工具进行代码性能分析(性能分析,而不是基准测试)?

问题2:您允许代码运行多长时间(统计数据:多少时间步长)?

问题3:情况有多大(如果情况适合高速缓存,则求解器的速度要快几个数量级,但我会错过与内存相关的过程)?

这是我如何做的一个例子。

我将基准测试(查看需要花费多长时间)与性能分析(确定如何使其更快)分开。探查器的速度并不重要。告诉您要解决的问题很重要。

我什至不喜欢“概要分析”一词,因为它会像直方图那样让人联想到图像,其中每个例程都有一个成本线,或者说是“瓶颈”,因为这意味着代码中只需要保留一小部分固定。这两件事都意味着某种时序和统计信息,您认为对于它们而言准确性很重要。放弃对计时准确性的见识是不值得的。

该方法我用的是随机暂停,并有一个完整的案例研究和幻灯片在这里。探查器瓶颈世界视图的一部分是,如果您什么都没找到,就什么也找不到了;如果您找到了什么并获得一定百分比的加速,则表示胜利并退出。Profiler爱好者几乎从不说他们能获得多大的提速,并且广告仅显示人为设计的问题,这些问题易于发现。随机暂停会发现问题的难易程度。然后解决一个问题就暴露了其他问题,因此可以重复该过程,以提高综合速度。

根据我在众多示例中的经验,方法是这样的:我可以找到一个问题(通过随机暂停)并加以解决,从而使速度提高了一些百分比,例如30%或1.3倍。然后我可以再做一次,找到另一个问题并解决它,获得另一个提速,也许不到30%,也许更多。然后,我可以重复多次,直到我真的找不到其他要修复的东西为止。最终的加速因素是各个因素的累加结果,并且可能非常大-在某些情况下为几个数量级。

插入:只是为了说明最后一点。有一个详细的例子在这里,用幻灯片和所有的文件,说明如何的730X的加速在一系列问题清除的实现。第一个版本每工作单位花费2700微秒。问题A被删除,使时间减少到1800,并将剩余问题的百分比放大了1.5倍(2700/1800)。然后B被删除。此过程进行了六次迭代,从而使速度提高了将近3个数量级。但是,分析技术必须确实有效,因为如果未发现任何这些问题,即,如果您到达错误地认为无法采取任何其他措施的地步,则该过程将停止。

消除多个问题以提高速度的描述

插入:换句话说,这是消除了连续出现的问题后的总加速因子的图表:

在此处输入图片说明

因此,对于Q1而言,对于一个简单的计时器进行基准测试就足够了。对于“概要分析”,我使用随机暂停。

问题2:我给它提供了足够的工作量(或只是绕了一圈),所以它运行的时间足以暂停。

Q3:一定要给它实际的大量工作量,这样您就不会错过缓存问题。这些将在执行内存提取的代码中显示为样本。


迈克,您是否喜欢在没有可视IDE的情况下如何进行随机暂停?这个过程可以某种方式自动化吗?
马修·埃米特

@Matthew:我知道有类似pstack和的工具lsstack,但我确实认为这是调试过程中更常见的过程。因此,即使我可以使用的最好的调试器是gdb,它也能完成工作。使用调试器,您可以检查数据,并且当单独的堆栈不能告诉您足够的信息时,这可以有所作为。
Mike Dunlavey 2012年

9

穷人的分析器基本上是一个gdb脚本样本调用堆栈。您仍然需要调试符号。它仍然很慢,但是由于它没有实现虚拟机来在其上运行代码,因此通常比callgrind完成任务要快且足够。

我已经在粒子物理分析仪上取得了一定的成功(即,我演示了该代码没有任何可怕的热点,并且优化将需要更好的算法)。


1
+缺乏证据并不代表缺乏证据:)穷人的分析者应该做的是减少痕迹并不会使痕迹塌陷,而是让您看到它们。与简单的功能时间估计相比,人眼在检测有用模式方面要好得多,而且如果您看到可以在最少2个样本上进行改进的情况,则将大有帮助。它将保存的分数X是模式为2 / N的beta分布,其中N是您检查的迹线数,加速因子将为1 /(1-X),这可能很大。
Mike Dunlavey '04年

2

为了增加可用的最佳答案,Rice开发了一个工具,该工具可以自动执行堆栈采样,因此开销很小:

http://hpctoolkit.org/


看起来不错,不过(抱歉)我在这里戴上了防火帽。我不优化编译器优化的代码,因为很难看整齐的代码中发生了什么。我正在修剪的东西不是优化程序可以处理的事情- 反复调用explog使用相同的参数,或者矩阵运算花费所有时间解码选项。我会尽可能地调音,然后打开-O3。
Mike Dunlavey 2013年

工具是工具,只有在用户了解并了解其局限性时才有用。我认为永远不会有一个“完美的探查器”,从理解方程式的输出和知道如何使用信息的角度来看,它完全可以将用户从方程式中删除。
Reid.Atcheson

1

Allinea MAP是一种商业开发并受支持的采样分析器,因此,如您先前的回答中所建议的HPC Toolkit一样,可以在生产规模的作业上运行。

这种工具指出了CPU瓶颈或MPI通信不畅,但是对整个工作进行概要分析的整个监督对于发现意外问题可能是无价的。

在CFD代码的核心内核之外,通常会有一些令人垂涎的性能低下的地方,在意料之外的领域。不管是使用GDB手动完成还是使用HPC Toolkit和Allinea MAP之类的工具完成随机堆栈采样,都是找到它们的最佳方法。如果某些事情对性能很重要,它将显示出来。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.