如何使用KCachegrind和Callgrind仅测量我的部分代码?

时间:2015-10-02 10:26:19

标签: c++ valgrind callgrind kcachegrind

我想使用 valgrind 来分析我的代码。问题是,我有一个我不感兴趣的巨大启动序列。

我在 valgrind / callgrind.h 中找到了应该帮助我的定义:

  • CALLGRIND_START_INSTRUMENTATION
  • CALLGRIND_STOP_INSTRUMENTATION
  • CALLGRIND_DUMP_STATS

根据this article,我必须使用以下选项执行 valgrind

valgrind --tool=callgrind --instr-atstart=no ./application

当我这样做时,会创建两个文件:

  • callgrind.out.16060
  • callgrind.out.16060.1

然后我想使用kcachegrind来显示我的结果。这很好用,但跳过我的启动序列的makros似乎什么也没做。我只需要在我想要的地方测量性能,我该怎么办?

2 个答案:

答案 0 :(得分:0)

我现在知道了,但我不能100%确定原因。我将尝试描述一下我的代码:

我有一个Application类,负责很多子系统。在我最初的尝试中,我试图像这样测量应用程序内部的性能:

act

由于某种原因,忽略了定义,我得到了整个构造函数的性能度量以及在ComplexSystem成员的configure()调用中完成的所有操作。

所以现在我使用这个似乎有效的代码:

int main(int argc, char *argv[])
{
    Application a(argc, argv);
    return a.exec();
}

void Application::Application(int &argc, char **argv)
{
    m_pComplexSystem = new ComplexSystem();
    m_pComplexSystem->configure();

    CALLGRIND_START_INSTRUMENTATION;
    m_Configurator->start();    
}

Application::~Application()
{
    CALLGRIND_STOP_INSTRUMENTATION;
    CALLGRIND_DUMP_STATS;
    m_pComplexSystem ->stop();

    delete m_pComplexSystem;
    m_pComplexSystem = 0;
}

虽然它与我原来的尝试并不完全相同,但我现在可以开始寻找慢功能了。

答案 1 :(得分:0)

假设您有以下开源程序:

int main()
{
    function1();

    function2();
    
    return 0;
}

假设您只想在 Callgrind 上执行 function2()

一种方法是在Callgrind周围插入function2()宏,并重新编译程序(请与上面比较):

#include <valgrind/callgrind.h>
int main()
{
    function1();

    CALLGRIND_START_INSTRUMENTATION;
    CALLGRIND_TOGGLE_COLLECT;
        function2();
    CALLGRIND_TOGGLE_COLLECT;
    CALLGRIND_STOP_INSTRUMENTATION;

    return 0;
}

在某些情况下,可能找不到 callgrind.h,请参阅 here for a similar problem。可能的解决方案是安装/编译 valgrind-devel,请参阅 this answer

最后,您需要在 callgrind 命令中添加两个新选项,例如:

valgrind --tool=callgrind \
    --collect-atstart=no --instr-atstart=no \ #new options
    <program>

这个答案是this entry的扩展。