【问题标题】:Kcachegrind/callgrind is inaccurate for dispatcher functions?Kcachegrind/callgrind 对于调度程序功能不准确?
【发布时间】:2011-11-21 06:34:12
【问题描述】:

我有一个模型代码,在该代码上 kcachegrind/callgrind 报告了奇怪的结果。这是一种调度程序功能。调度员从 4 个地方调用;每个调用都说,要运行哪个实际的 do_J 函数(所以 first2 将只调用 do_1do_2 等等)

源码(这是实际代码的模型)

#define N 1000000

int a[N];
int do_1(int *a) { int i; for(i=0;i<N/4;i++) a[i]+=1; }
int do_2(int *a) { int i; for(i=0;i<N/2;i++) a[i]+=2; }
int do_3(int *a) { int i; for(i=0;i<N*3/4;i++) a[i]+=3; }
int do_4(int *a) { int i; for(i=0;i<N;i++) a[i]+=4; }

int dispatcher(int *a, int j) {
    if(j==1) do_1(a);
    else if(j==2) do_2(a);
    else if(j==3) do_3(a);
    else do_4(a);
}

int first2(int *a) { dispatcher(a,1); dispatcher(a,2); }
int last2(int *a) { dispatcher(a,4); dispatcher(a,3); }
int inner2(int *a) { dispatcher(a,2); dispatcher(a,3); }
int outer2(int *a) { dispatcher(a,1); dispatcher(a,4); }

int main(){
    first2(a);
    last2(a);
    inner2(a);
    outer2(a);
}

gcc -O0编译;与valgrind --tool=callgrind 通话; kcache 使用 kcachegrindqcachegrind-0.7 研磨。

这是应用程序的完整调用图。 do_J 的所有路径都通过调度程序,这很好(do_1 隐藏得太快了,但它真的在这里,只剩下 do_2)

让我们关注do_1,看看是谁叫的(这张图不对):

我认为这很奇怪,只有first2outer2 称为do_1,但不是全部。

是 callgrind/kcachegrind 的限制吗?如何获得带有权重的准确调用图(与每个函数的运行时间成正比,无论有无子函数)?

【问题讨论】:

    标签: valgrind call-graph kcachegrind callgrind


    【解决方案1】:

    是的,这是 callgrind 格式的限制。它不存储完整的跟踪;它只存储父子调用信息。

    有一个带有 pprof/libprofiler.so CPU 分析器的 google-perftools 项目,http://google-perftools.googlecode.com/svn/trunk/doc/cpuprofile.htmllibprofiler.so 可以使用 calltraces 获取配置文件,它将存储每个跟踪事件和完整的回溯。 pprof 将 libprofile 的输出转换为图形格式或调用grind 格式。在全视图中,结果将与 kcachegrind 中的相同;但如果您将专注于某些功能,例如do_1 使用 pprof 的选项焦点;专注于功能时,它将显示准确的调用树。

    【讨论】:

    猜你喜欢
    • 2015-04-04
    • 2017-05-26
    • 2016-02-19
    • 2021-09-13
    • 2011-12-30
    • 2011-01-23
    • 1970-01-01
    • 2010-10-26
    相关资源
    最近更新 更多