Callgrind:调用图生成缓存和分支预测分析器

要使用此工具,必须--tool=callgrind在Valgrind命令行上指定 。

6.1。概观

Callgrind是一个分析工具,可以将程序运行中的函数之间的通话记录作为调用图记录。默认情况下,收集的数据由执行的指令数,它们与源行的关系,函数之间的调用者/被调用者关系以及这些调用的数量组成。可选地,高速缓存模拟和/或分支预测(类似于Cachegrind)可以产生关于应用的运行时行为的更多信息。

在程序终止时,将配置文件数据写入文件。为了呈现数据,并对分析进行交互式控制,提供了两个命令行工具:

callgrind_annotate

该命令读入配置文件数据,并打印排序的功能列表,可选地使用源注释。

对于数据的图形可视化,请尝试 KCachegrind,它是基于KDE / Qt的GUI,可以轻松导航Callgrind生成的大量数据。

callgrind_control

此命令使您能够交互地观察和控制当前在Callgrind的控制下运行的程序的状态,而不停止程序。您可以获取统计信息以及当前的堆栈跟踪,您可以请求归零或转储配置文件数据。

6.1.1。功能

Cachegrind收集平面配置文件数据:事件计数(数据读取,高速缓存未命中等)直接归因于其发生的功能。此成本归属机制称为自身 他归属。

Callgrind通过在功能调用边界传播成本来扩展此功能。如果功能foo调用 bar,则将成本bar加入 foo成本中。当应用于整个程序时,它建立了所谓的包容性 成本的图片,即每个功能的成本包括直接或间接的所有功能的成本。

作为一个例子,包容成本 main应该几乎是总计费用的100%。由于main运行之前产生的成本 ,例如运行时链接器的初始化和全局C ++对象的构建,其包容成本main 并不完全为总程序成本的100%。

与呼叫图一起,您可以从main其中大部分程序的成本开始找到特定的呼叫链 。来电/被叫成本归属对于从多个呼叫站点调用的分析功能也是有用的,其中优化机会取决于呼叫者中更改的代码,特别是通过减少呼叫计数。

Callgrind的缓存模拟是基于Cachegrind的。首先阅读Cachegrind的文档:缓存和分支预测分析器。下面的内容描述了除了Cachegrind的功能之外支持的功能。

Callgrind检测函数调用和返回的能力取决于运行平台的指令集。它在x86和amd64上效果最好,不幸的是,目前在PowerPC,ARM,Thumb或MIPS代码上并不能很好地工作。这是因为在这些指令集中没有明确的调用或返回指令,所以Callgrind必须依赖启发式来检测调用和返回。

6.1.2。基本用法

与Cachegrind一样,您可能想要使用调试信息(-g选项)进行编译,并且优化已打开。

要启动程序的配置文件运行,请执行:

valgrind --tool = callgrind [callgrind options]你的程序[程序选项]

当模拟运行时,您可以通过以下方式观察执行:

callgrind_control -b

这将打印出当前的回溯。要使用事件计数注释回溯,请运行

callgrind_control -e -b

程序终止后,将生成一个名为的配置文件数据文件 callgrind.out.<pid> ,其中pid是要分析的程序的进程ID。数据文件包含有关执行功能的程序中进行的调用以及 指令读取(Ir)事件计数的信息。

要从配置文件数据文件生成功能函数摘要,请使用

callgrind_annotate [options] callgrind.out。<pid>

此摘要类似于使用cg_annotate从Cachegrind运行得到的输出:函数列表按功能的排他成本排序,这也是显示的。Callgrind的其他功能重要是以下两个选项:

  • --inclusive=yes:不使用功能的独占成本作为排序顺序,使用并显示包含成本。

  • --tree=both:交叉进入顶级功能列表,每个功能的呼叫者和被呼叫者的信息。在这些代表执行的呼叫的行中,成本给出了在呼叫中花费的事件数。缩进,在每个功能之上,有呼叫者列表,以及下面的被叫列表。给定功能(呼叫者线路)的呼叫中的事件总和以及来自函数(被叫线路)的呼叫中的事件的总和以及自身成本给出了该功能的总包含成本。

使用--auto=yes获得注释的源代码,它的源可以找到所有相关功能。除了生成的源注释外 cg_annotate,您还可以看到具有呼叫计数的带注释的呼叫站点。有关所有其他选项,请参阅(Cachegrind)文档 cg_annotate

为了更好的通话图浏览体验,强烈建议您使用KCachegrind。如果您的代码的周期成本(以递归方式相互调用的函数集合)的大部分成本,则必须使用KCachegrind,因为callgrind_annotate 目前不执行任何循环检测,这在本例中获得正确的结果很重要。

如果您还有兴趣测量程序的缓存行为,请使用Callgrind选项 --cache-sim=yes。对于分支预测模拟,使用--branch-sim=yes。预计进一步放缓约2倍。

如果您要配置文件的程序段位于运行中间,则无需任何概要分析即可 快速转到此部分,然后启用概要分析是有益的。这通过使用命令行选项 --instr-atstart=no 并在shell中运行: callgrind_control -i on在有趣的代码部分执行之前实现。要精确指定分析应该开始的代码位置,请使用客户端请求CALLGRIND_START_INSTRUMENTATION

如果您想要看到汇编代码级别的注释,请指定 --dump-instr=yes。这将以指令粒度产生配置文件数据。请注意,生成的配置文件数据只能使用KCachegrind进行查看。对于汇编注释,还可以看到函数内的控制流的更多细节,即(条件)跳转也是有趣的。这将通过进一步指定来收集 --collect-jumps=yes

6.2。高级用法

6.2.1。从一个程序运行多次分析转储

有时您对整个程序运行的特性不感兴趣,但只对其一小部分感兴趣,例如执行一个算法。如果存在多种算法,或者一种算法运行不同的输入数据,则为单个程序运行的不同部分获取不同的配置文件信息甚至是有用的。

配置文件数据文件具有表单名称

callgrind.out。PIDpart - threadID

其中pid是运行程序的PID,部分是在每个转储上递增的数字(在程序终止时跳过“part”用于转储), threadID是一个线程标识(“-threadID”仅在您请求时使用单个线程的转储--separate-threads=yes)。

在Callgrind的监督下运行程序时,有多种方式可以生成多个配置文件转储。然而,所有方法都会触发相同的操作,即“自上次转储或程序启动以来的所有配置文件信息,以及零成本计数器之后”。为了允许调零成本计数器而不倾倒,第二个动作是“现在零成本计数器”。不同的方法是:

  • 转储程序终止。 这种方法是标准的方式,您不需要任何特殊的操作。

  • 自发,互动倾销。使用

    callgrind_control -d [hint [PID / Name]]

    请求使用PID或Name转储受监督应用程序的配置文件信息。 提示是一个任意字符串,您可以选择指定以后能够区分配置文件转储。转储完全写入之前,控制程序将不会终止。请注意,应用程序必须正在运行才能检测dump命令。因此,对于GUI应用程序,请调整窗口大小或服务器的大小,发送请求。

    如果您使用KCachegrind 浏览配置文件信息,可以使用工具栏按钮强制转储。这将在转储写入后请求转储并触发重新加载。

  • 执行指定数量的基本块后定期转储。为此,请使用命令行选项--dump-every-bb=count

  • 在进入/离开指定功能时倾倒。 使用选项--dump-before=function 和--dump-after=function。在进入功能之前要调零成本计数器,请使用 --zero-before=function

    您可以为不同的功能多次指定这些选项。函数规范支持通配符:例如 --dump-before='foo*',在输入任何以foo开头的函数之前,用来生成转储 。

  • 程序控制倾销。 插入 CALLGRIND_DUMP_STATS; 到代码中您想要进行配置文件转储的位置。使用 CALLGRIND_ZERO_STATS;仅零轮廓计数器。有关Callgrind特定客户端请求的更多信息,请参阅客户端请求参考

如果您正在运行多线程应用程序并指定命令行选项--separate-threads=yes,则会自动对每个线程进行概要分析,并创建自己的配置文件转储。因此,最后两个方法将仅生成当前正在运行的线程的一个转储。使用其他方法,您将在转储请求上获得多个转储(每个线程一个)。

6.2.2。限制收集事件的范围

默认情况下,每当事件发生时(例如指令执行或缓存命中/未命中),Callgrind会将它们聚合到事件计数器中。但是,您可能只对给定功能中发生的情况或从给定的程序阶段开始感兴趣。为此,您可以禁用不感兴趣的程序部件的事件聚合。事件归功于功能以及每个程序阶段产生单独的输出都可以通过其他方法来完成(见上一节),禁用聚合有两个好处。首先,这是非常精细的(例如仅用于函数内的循环)。第二,valgrind --tool=none

有两个方面影响了Callgrind在程序执行的某个时间点聚合事件。首先是收集状态。如果这是关闭,则不会进行聚合。通过更改收集状态,可以非常精细地控制事件聚合。然而,Callgrind的执行速度没有多大的区别。默认情况下,收集被打开,但可以通过不同的方式被禁用(见下文)。其次,Callgrind正在运行的仪器模式。此模式可以打开或关闭。如果仪器关闭,则不会对程序中的操作进行任何观察,因此不会将任何操作转发给可能触发事件的模拟器。到底, 不会汇总任何事件。巨大的好处是仪器关闭的速度要高得多。然而,这只应该谨慎使用,并且粗略地使用:每个模式更改都会重置模拟器状态(即,内存块是否被缓存),并刷新Valgrinds内部高速缓存的测试代码块,从而在切换时产生延迟损失时间。此外,由于识别出的高速缓存未命中,因此在切换仪表后,缓存模拟器的结果将会发生偏移(如果您关心这种预热效果,那么您应该确保在转换仪器后立即关闭收集状态模式开启)。然而,切换仪器状态对于跳过更大的程序阶段(如初始化阶段)非常有用。默认情况下,仪器打开,但与收集状态一样,可以通过各种方式进行更改。

Callgrind可以通过指定选项关闭仪器模式--instr-atstart=no。之后,仪器可以通过两种方式进行控制:首先,与

callgrind_control -i on

(并通过指定“关”而不是“开”)再次关闭)。其次,仪表状态可以用编程宏改变CALLGRIND_START_INSTRUMENTATION; 和CALLGRIND_STOP_INSTRUMENTATION;

类似地,程序启动时的收集状态可以被关闭--instr-atstart=no。在执行期间,可以使用宏程序控制CALLGRIND_TOGGLE_COLLECT;。此外,您可以通过使用限制事件收集到特定的功能--toggle-collect=function。这将在进入和离开指定的功能时切换收集状态。当此选项生效时,程序启动时的默认收集状态为“off”。只有在给定功能内部运行的事件才会被收集。给定函数的递归调用不会触发任何操作。可以多次给出此选项以指定不同的兴趣功能。

6.2.3。计算全球巴士事件

为了在多线程代码中的线程之间访问共享数据,需要进行同步以避免竞争条件。同步原语通常通过原子指令来实现。但是,过度使用这些说明可能会导致性能问题。

为了能够分析这个问题,Callgrind可以选择性地对所执行的原子指令数进行计数。更准确地说,对于x86 / x86_64,这些是使用锁前缀的指令。对于支持LL / SC的架构,这些是执行的SC指令的数量。对于这两者,使用“全球公共汽车事件”一词。

用于全局总线事件的事件类型的短名称是“Ge”。计数全球总线事件,使用--collect-bus=yes

6.2.4。避免循环

非正式地,循环是一组以递归方式相互呼叫的函数。

正式地说,一个循环是一个非空的函数集合S,使得对于S中的每对函数F和G,可以从F到G(可能经由中间函数)以及从G到F调用。此外, S必须是最大的 - 也就是满足该属性的最大函数集。例如,如果从S内部调用第三函数H并调用S,则H也是循环的一部分,并且应包括在S中。

递归在程序中很常见,因此循环有时会出现在Callgrind的调用图输出中。但是,本章的标题应该提出两个问题:循环是什么坏事,这使你想避免这些问题?并且:如何避免循环而不改变程序代码?

周期本身并不差,但往往使您的代码的性能分析更加困难。这是因为一个周期内的通话费用是无意义的。包容性成本的定义,即功能的自身成本加上被调用者的包容性成本,需要功能之间的拓扑顺序。对于循环,这并不适用:循环中的函数的被调用者包括函数本身。因此,KCachegrind会循环检测并跳过循环内调用的任何包含成本的可视化。此外,循环中的所有功能都被折叠成类似的人工功能Cycle 1

现在,当一个程序暴露出很大的周期(对于一些GUI代码,或者一般使用事件或基于回调的编程风格的代码),你会失去漂亮的属性,让您通过跟踪调用链来定位瓶颈 main,包容成本。此外,KCachegrind失去了显示通话图的有趣部分的能力,因为它使用包容性成本来切断不感兴趣的区域。

尽管循环中包含成本是无意义的,但可视化的最大缺点是可能暂时关闭KCachegrind中的循环检测,这可能导致误导性的可视化。然而,由于独立调用链的不合逻辑叠加,通常会出现循环,因为配置文件结果将会看到一个循环。以非常小的测量包容成本忽略不感兴趣的电话会破坏这些周期。在这种情况下,通过不检测循环的不正确处理仍然给出有意义的分析可视化。

必须注意的是,目前,callgrind_annotate 根本没有执行任何循环检测。对于具有函数递归的程序执行,例如可以打印100%以上的无含义成本。

在描述为什么周期不利于分析时,值得一提的是循环避免。这里的主要观点是,配置文件数据中的符号不​​一定与程序中找到的符号完全一致。相反,符号名称可以编码来自当前执行上下文的附加信息,例如当前函数的递归级别,或甚至导致该函数的调用链的某些部分。尽管将附加信息编码到符号中能够避免周期,但必须小心使用,以免引起符号爆炸。后者为Callgrind提供了可能的内存不足条件和大型数据文件的大量内存需求。

在Callgrind的简档数据输出中避免循环的另一个可能性是简单地省略调用图中的给定函数。当然,这也会忽略来自和忽略的功能的任何呼叫信息,从而可以打破一个周期。候选人通常是事件驱动代码中的调度程序函数。忽略对函数的调用的选项是 --fn-skip=function。除了可能的中断周期之外,这在Callgrind中用于跳过PLT部分中的蹦床功能,用于调用共享库中的函数。你可以看到差异,如果你的配置文件--skip-plt=no。如果一个呼叫被忽略,其成本事件将被传播到封闭的功能。

如果您有递归函数,您可以通过指定来区分前10个递归级别 --separate-recs10=function。或者对于所有功能 --separate-recs=10,但这会给你更大的配置文件数据文件。在配置文件数据中,您将看到“func”的递归级别作为名称为“func”,“func'2”,“func'3”等的不同功能。

如果您的程序中有“A> B> C”和“A> C> B”的调用链,则通常会得到“假”循环“B <> C”。使用 --separate-callers2=B --separate-callers2=C和功能“B”和“C”将视为不同的功能,具体取决于直接来电者。使用撇号将这个“上下文”附加到函数名中,你会得到“A> B'A”C'B“和”A> C'A“B'C”,并且不会有循环。使用 --separate-callers=2以获取所有功能的2呼叫者的依赖。请注意,这样做会增加配置文件数据文件的大小。

6.2.5。分岔程序

如果您的程序分叉,该子将继承所有为父级收集的分析数据。要从小孩中的空配置文件计数器值开始,客户端请求 CALLGRIND_ZERO_STATS; 可以直接插入到子程序执行的代码中 fork

但是,您必须确保输出文件格式字符串(受控制--callgrind-out-file)确实包含 %p(默认情况下为true)。否则,父母和孩子的输出将相互覆盖或混合,这几乎肯定不是你想要的。

您将能够通过callgrind_control从父级单独控制新的孩子。

6.3。Callgrind命令行选项

在下面,选项分为几类。

一些选项允许指定函数/符号名称,例如 --dump-before=function或 --fn-skip=function。所有这些选项可以为不同的功能多次指定。此外,函数规范实际上是通过支持使用通配符'*'(零个或多个任意字符)和'?' (恰好一个任意字符),类似于shell中的文件名称globbing。这个特性对于C ++来说是非常重要的,因为没有通配符使用,这个功能必须被全面的指定,包括参数签名。

6.3.1。转储创建选项

这些选项会影响配置文件数据文件的名称和格式。

--callgrind-out-file=<file>

将配置文件数据写入 file而不是默认的输出文件 callgrind.out.<pid>。的 %p%q格式说明可以用来嵌入进程ID和/或名称的环境变量的内容,由于是用于芯选项的情况下--log-file。当进行多次转储时,文件名进一步修改; 见下文。

--dump-line=<no|yes> [default: yes]

这指定事件计数应以源行粒度执行。这允许使用调试信息(-g)编译的源的源注释。

--dump-instr=<no|yes> [default: no]

这指定事件计数应按照指令粒度执行。这允许汇编代码注释。目前结果只能由KCachegrind显示。

--compress-strings=<no|yes> [default: yes]

此选项会影响配置文件数据的输出格式。它指定字符串(文件和函数名称)是否应由数字标识。这缩小了文件,但是使人们更难阅读(在任何情况下都不推荐)。

--compress-pos=<no|yes> [default: yes]

此选项会影响配置文件数据的输出格式。它指定数字位置是否始终被指定为绝对值,或允许与先前数字相对。这缩小了文件大小。

--combine-dumps=<no|yes> [default: no]

当启用时,当要生成多个配置文件数据部分时,这些部件将附加到同一个输出文件。不建议。

6.3.2。活动选项

这些选项指定何时执行与事件计数相关的操作。对于交互式控制使用callgrind_control。

--dump-every-bb=<count> [default: 0, never]

每个count基本块转储配置文件数据。只有当运行Valgrind的内部调度程序时才检查是否需要转储。因此,有用的最小设置约为100000.计数是一个64位值,可以使长时间转储周期成为可能。

--dump-before=<function>

进入时倾倒function

--zero-before=<function>

进入时将所有费用归零function

--dump-after=<function>

离开时倾倒function

6.3.3。数据收集选项

这些选项指定何时将事件聚合到事件计数中。另请参阅限制事件收集的范围

--instr-atstart=<yes|no> [default: yes]

指定您是否希望Callgrind从程序开始启动仿真和分析。当设置时no,Callgrind将无法收集任何信息,包括通话,但它最多将减缓约4,这是最低Valgrind开销。仪器可以通过交互方式启用 callgrind_control -i on

请注意,生成的调用图很可能不包含main,但将包含启用了检测功能后执行的所有函数。仪器也可以编程启用/禁用。请参阅callgrind.h您的源代码中必须使用的宏的Callgrind include文件 。

对于高速缓存模拟,当程序运行后期开启仪器时,结果将不太准确,因为模拟器在此刻以空白缓存开始。稍后打开事件收集以应对此错误。

--collect-atstart=<yes|no> [default: yes]

指定在配置文件运行开始时是否启用事件收集。

只能看看程序的一些部分,你有两种可能性:

  1. 进入要配置的程序部件之前的零事件计数器,并在离开该程序部件后将事件计数器转储到文件中。

  2. 根据需要打开/关闭收集状态,只有在要配置的程序部分内部才能看到事件计数器发生。

如果要配置文件的程序部分被调用多次,可以使用第二个选项。选项1,即创建大量转储在这里是不实际的。

可以使用选项在给定功能的进入和退出时切换收集状态--toggle-collect。如果使用此选项,则开始时应禁用收集状态。注意--toggle-collect 隐含集的规范 --collect-state=no

收集状态也可以通过将客户端请求 CALLGRIND_TOGGLE_COLLECT ; 插入到所需的代码位置来切换 。

--toggle-collect=<function>

在入口/出口处切换收藏function

--collect-jumps=<no|yes> [default: no]

这指定是否收集(条件)跳转的信息。如上所述,callgrind_annotate目前无法显示数据。您必须使用KCachegrind在注释代码中获取跳转箭头。

--collect-systime=<no|yes> [default: no]

这指定是否应收集系统调用时间的信息。

--collect-bus=<no|yes> [default: no]

这指定是否应该收集执行的全局总线事件的数量。事件类型“Ge”用于这些事件。

6.3.4。成本实体分离选项

这些选项指定如何将事件计数归因于执行上下文。例如,它们指定是否应考虑到导出功能的递归级别或调用链,以及是否应考虑线程ID。另请参阅避免循环

--separate-threads=<no|yes> [default: no]

此选项指定是否应为每个线程单独生成配置文件数据。如果是,则文件名称将附加“-threadID”。

--separate-callers=<callers> [default: 0]

在调用链中最多只能分配上下文<callers>函数。请参阅避免循环

--separate-callers<number>=<function>

单独number呼叫者function。请参阅避免循环

--separate-recs=<level> [default: 2]

大多数level级别分离函数递归。请参阅避免循环

--separate-recs<number>=<function>

单独的number递归function。请参阅避免循环

--skip-plt=<no|yes> [default: yes]

忽略来自PLT部分的呼叫。

--skip-direct-rec=<no|yes> [default: yes]

忽略直接递归。

--fn-skip=<function>

忽略来自/来自给定功能的调用。例如,如果您有一个呼叫链A> B> C,并且指定功能B被忽略,您将只看到A> C.

这是非常方便的跳过处理回调行为的函数。例如,使用Qt图形库中的信号/时隙机制,您只想看到发出信号的功能来调用与该信号相连的插槽。首先,确定真正的呼叫链,查看需要跳过的功能,然后使用此选项。

6.3.5。模拟选项

--cache-sim=<yes|no> [default: no]

指定是否要进行全缓存模拟。默认情况下,只有指令读取访问将被计数(“Ir”)。通过缓存模拟,启用其他事件计数器:指令读取(“I1mr”/“ILmr”),数据读取访问(“Dr”)和相关高速缓存未命中(“D1mr”/“DLmr”),数据写入访问(“Dw”)和相关高速缓存未命中(“D1mw”/“DLmw”)。有关更多信息,请参阅Cachegrind:缓存和分支预测分析器

--branch-sim=<yes|no> [default: no]

指定是否要进行分支预测模拟。启用其他事件计数器:执行条件分支的数量和相关的预测器丢失(“Bc”/“Bcm”),执行跳转地址预测器(“Bi”/“Bim”)的间接跳转和相关未命中。

6.3.6。缓存模拟选项

--simulate-wb=<yes|no> [default: no]

指定是否应该模拟回写行为,允许区分具有和不具有回写的LL缓存未命中。Cachegrind / Callgrind的高速缓存模型没有指定写入与写回行为,并且这与生成的错误计数的数量无关。然而,通过显式回写模拟,可以决定错误是否触发不仅加载新的高速缓存行,而且还必须在之前发生脏高速缓存行的回写。新的脏错误事件分别是ILdmr,DLdmr和DLdmw,因为指令读取,数据读取和数据写入。当他们产生两个内存交易时,他们应该考虑到与正常错误相关的双倍时间估计。

--simulate-hwpref=<yes|no> [default: no]

指定是否应添加硬件预取器的仿真,通过比较访问以分离到每个页面,能够检测第二级缓存中的流访问。由于模拟不能决定预取的任何时序问题,所以假设任何硬件预取触发在实际访问完成之前成功。因此,这通过覆盖所有可能的流访问给出了最佳情况。

--cacheuse=<yes|no> [default: no]

指定是否应收集高速缓存行的使用。对于每个缓存行,从加载到被驱逐,确定访问次数以及实际使用的字节数。此行为与触发加载缓存行的代码相关。与错误计数器相反,它显示出错误缓存行为(即延迟)发生的症状的位置,使用计数器尝试确定原因(即具有不良访问行为的代码)。新的计数器的定义方式使得较差的行为导致更高的成本。AcCost1和AcCost2分别是L1和LL缓存的时间局部性差的计数器。这是通过对每个高速缓存行的访问次数的互逆值进行求和来完成的,乘以1000(仅允许整数成本)。例如,对于具有5个读取访问的给定源行,值为5000的AcCost意味着对于每次访问,新的高速缓存行被加载并且之后被直接驱逐而不进一步访问。同样,SpLoss1 / 2分别显示L1和LL缓存的空间局部性差。它给出了加载到缓存中但从未访问的字节的空间损失计数。它确定代码访问数据的方式,使缓存空间浪费。这暗示了内存中数据结构的布局不佳。假设给定源行的高速缓存行大小为64字节,缺少100个L1,则将触发向64位字节加载到L1中。如果SpLoss1显示此行的值为3200, 这意味着一半的加载数据从未被使用,或者使用更好的数据布局,只需要一半的缓存空间。请注意,对于高速缓存行使用计数器,目前无法提供有意义的包容性成本。因此,这些柜台的包容性成本应该被忽略。

--I1=<size>,<associativity>,<line size>

指定级别1指令高速缓存的大小,关联度和行大小。

--D1=<size>,<associativity>,<line size>

指定1级数据缓存的大小,关联度和行大小。

--LL=<size>,<associativity>,<line size>

指定最后一级缓存的大小,关联性和行大小。

6.4。Callgrind监视器命令

Callgrind工具提供由Valgrind gdbserver 处理的监视器命令(请参阅Valgrind gdbserver的Monitor命令处理)。

  • dump [<dump_hint>] 请求转储配置文件数据。

  • zero 请求归档配置文件数据计数器。

  • instrumentation [on|off] 请求设置(如果给定参数开/关)或获取当前的仪器状态。

  • status 请求打印出一些状态信息。

6.5。Callgrind特定的客户端请求

Callgrind提供以下特定的客户端请求 callgrind.h。请参阅该文件的参数的确切细节。

CALLGRIND_DUMP_STATS

在代码中的指定位置强制生成轮廓转储,仅针对当前线程。写入计数器将被重置为零。

CALLGRIND_DUMP_STATS_AT(string)

CALLGRIND_DUMP_STATS与之相同,但允许指定一个字符串以能够区分配置文件转储。

CALLGRIND_ZERO_STATS

将当前线程的配置文件计数器重置为零。

CALLGRIND_TOGGLE_COLLECT

切换收集状态。这允许忽略关于配置文件计数器的事件。另见选项 --collect-atstart和 --toggle-collect

CALLGRIND_START_INSTRUMENTATION

如果尚未启用,请启动完整的Callgrind仪器。当高速缓存模拟完成时,这将刷新模拟高速缓存,并导致人为高速缓存预热阶段之后的高速缓存未命中,这在现实中不会发生。参见选项--instr-atstart

CALLGRIND_STOP_INSTRUMENTATION

如果尚未禁用,请停止完整的Callgrind仪器。这会刷新Valgrinds翻译缓存,之后不再需要额外的工具:它会以与Nulgrind相同的速度运行,即以最小的减速运行。使用它来加快Callgrind运行的无趣的代码部分。用于 CALLGRIND_START_INSTRUMENTATION重新启用仪器。参见选项 --instr-atstart

6.6。callgrind_annotate命令行选项

-h --help

显示选项摘要。

--version

显示callgrind_annotate的版本。

--show=A,B,C [default: all]

仅显示事件A,B,C的数字。

--sort=A,B,C

按事件A,B,C [事件列顺序]排序列。

--threshold=<0--100> [default: 99%]

我们感兴趣的计数(主要排序事件)的百分比。

--auto=<yes|no> [default: no]

注释包含有助于达到事件计数阈值的函数的所有源文件。

--context=N [default: 8]

在注释行之前和之后打印N行上下文。

--inclusive=<yes|no> [default: no]

向函数调用添加子程序成本。

--tree=<none|caller|calling|both> [default: none]

为每个功能打印其呼叫者,被叫功能或两者。

-I, --include=<dir>

添加dir到目录列表以搜索源文件。

6.7。callgrind_control命令行选项

默认情况下,callgrind_control对当前用户在Callgrind下运行的所有程序起作用。通过提供一个pids或程序名称作为参数,可以将操作限制为指定的Callgrind运行。默认操作是给出一些关于在Callgrind下运行的应用程序的简要信息。

-h --help

显示选项的简短说明,用法和摘要。

--version

显示callgrind_control的版本。

-l --long

显示工作目录,除了默认给出的简要信息。

-s --stat

显示关于活动的Callgrind运行的统计信息。

-b --back

在活动的Callgrind运行中显示每个线程的堆栈/后跟踪。对于堆栈跟踪中的每个活动功能,还显示自程序启动(或最后一次转储)以来的调用次数。此选项可以与-e组合以显示活动功能的包含成本。

-e [A,B,...] (默认值:全部)

显示事件计数器的当前每线程独占成本值。如果没有给出明确的事件名称,则会显示在给定Callgrind运行中收集的所有事件类型的数据。否则,仅显示事件类型A,B,...的数字。如果此选项与-b组合,则还提供每个活动堆栈帧的功能的包含成本。

--dump[=<desc>] (默认值:无说明)

请求倾倒个人资料信息。可选地,可以指定将描述作为引发触发转储动作的原因的信息的一部分写入转储。这可以用来区分多个转储。

-z --zero

将所有事件计数器置零

-k --kill

强制一个Callgrind运行被终止。

--instr=<on|off>

打开或关闭仪器仪表模式。如果Callgrind运行禁用了仪器,则不进行任何仿真,也不计算任何事件。这对于跳过不感兴趣的程序部件很有用,因为减速比较少(与Valgrind工具“none”一样)。另请参阅Callgrind选项--instr-atstart

--vgdb-prefix=<prefix>

指定由callgrind_control使用的vgdb前缀。callgrind_control内部使用vgdb来查找和控制活动的Callgrind运行。如果该--vgdb-prefix选项用于启动valgrind,则必须向callgrind_control提供相同的选项。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值