如何使用KCachegrind和Callgrind来测量我的代码的一部分



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

我在valgrind/callgrind.h中找到了一些定义:

  • CALLGRIND_START_INSTRUMENTATION
  • CALLGRIND_STOP_INSTRUMENTATION
  • CALLGRIND_DUMP_STATS

根据这篇文章,我必须执行valgrind以下选项:

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

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

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

然后我想使用kcachegrind来可视化我的结果。这工作得很好,但是用于跳过启动序列的makros似乎什么都不做。我要怎么做才能只在我想要的地方测量性能?

假设您有以下开源程序:

int main()
{
    function1();
    function2();
    
    return 0;
}

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

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

#include <valgrind/callgrind.h>
int main()
{
    function1();
    CALLGRIND_START_INSTRUMENTATION;
    CALLGRIND_TOGGLE_COLLECT;
        function2();
    CALLGRIND_TOGGLE_COLLECT;
    CALLGRIND_STOP_INSTRUMENTATION;
    return 0;
}

在某些情况下,callgrind.h可能找不到,参见这里的类似问题。可能的解决方案是安装/编译valgrind-devel,参见此答案。

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

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

这个答案是这个条目的延伸

我现在明白了,但我不是100%确定为什么。我将试着描述一下我的代码:

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

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;
}

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

那么现在我用这段代码,似乎可以工作:

int main(int argc, char *argv[])
{
    Application a(argc, argv);
    CALLGRIND_START_INSTRUMENTATION;
    int result = a.exec();
    CALLGRIND_STOP_INSTRUMENTATION;
    CALLGRIND_DUMP_STATS;
    return result;
}

虽然它与我最初的尝试不完全相同,但我现在可以开始寻找慢函数了

相关内容

  • 没有找到相关文章

最新更新