如何使用 KCachegrind 和 Callgrind 来测量我的部分代码?
How to use KCachegrind and Callgrind to measure only parts of my code?
我想使用 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 似乎什么都不做。我需要做什么才能只在我想测量的地方测量性能?
我现在明白了,但我不是 100% 确定为什么。我将尝试稍微描述一下我的代码:
我有一个应用程序 class 负责很多子系统。在我最初的尝试中,我尝试像这样测量应用程序内部的性能:
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;
}
虽然和我最初的尝试不完全一样,但我现在可以开始寻找慢函数了。
假设您有以下开源程序:
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
,请参阅 here for a similar problem. The likely solution is to install/compile valgrind-devel
, see this answer。
最后,您需要在 callgrind
命令中添加两个新选项,例如:
valgrind --tool=callgrind \
--collect-atstart=no --instr-atstart=no \ #new options
<program>
此答案是 this entry 的扩展。
我想使用 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 似乎什么都不做。我需要做什么才能只在我想测量的地方测量性能?
我现在明白了,但我不是 100% 确定为什么。我将尝试稍微描述一下我的代码:
我有一个应用程序 class 负责很多子系统。在我最初的尝试中,我尝试像这样测量应用程序内部的性能:
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;
}
虽然和我最初的尝试不完全一样,但我现在可以开始寻找慢函数了。
假设您有以下开源程序:
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
,请参阅 here for a similar problem. The likely solution is to install/compile valgrind-devel
, see this answer。
最后,您需要在 callgrind
命令中添加两个新选项,例如:
valgrind --tool=callgrind \
--collect-atstart=no --instr-atstart=no \ #new options
<program>
此答案是 this entry 的扩展。