我想以非标准方式描述我的执行情况。使用 gprof、Valgrind、Oprofile... 对于给定函数,我只能得到其执行时间的平均值。我想要的是获得这个执行时间的标准差。
例子:
void a()
sleep ( rand() % 10 + 10 )
void b()
sleep ( rand() % 14 + 2 )
main
for (1 .. 100)
a()
b()
使用标准工具,a 和b 函数将具有相似的行为。你知道有什么工具可以通过自动方法给我这个结果吗?
我已经用 TAU 进行了测试,但直到现在,它还不是很相关。这种方式我觉得是有解决办法的,但是我对TAU信心不足。如果有人是 Tau 专家,我会尝试保留所有函数执行时间,并在最后进行数学计算。但我不知道如何在 Tau 中指定它。
我想剖析 C/C++ 代码,但如果您在其他编程语言方面有任何领先优势,我愿意。
最佳答案
分析工具并不神奇,您可以在几行中为任何目的推出自己的分析工具。
可能是这样的:
// code profile.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
class cProfile
{
public:
// construct profiler for a particular scope
// call at begining of scope to be timed
// pass unique name of scope
cProfile( const char* name )
{
myName = string( name );
QueryPerformanceCounter( (LARGE_INTEGER *)&myTimeStart );
}
// destructor - automatically called when scope ends
~cProfile();
// constructor - produces report when called without parameters
cProfile();
private:
typedef accumulator_set<__int64, stats<tag::variance(lazy)> > acc_t;
static map < string, acc_t > myMap;
string myName;
__int64 myTimeStart;
};
map < string, accumulator_set<__int64, stats<tag::variance(lazy)> > > cProfile::myMap;
cProfile::~cProfile()
{
__int64 t=0;
QueryPerformanceCounter( (LARGE_INTEGER *)&t );
t -= myTimeStart;
map < string, acc_t >::iterator p = myMap.find( myName );
if( p == myMap.end() ) {
// this is the first time this scope has run
acc_t acc;
pair<string,acc_t > pr(myName,acc);
p = myMap.insert( pr ).first;
}
// add the time of running to the accumulator for this scope
(p->second)( t );
}
// Generate profile report
cProfile::cProfile()
{
__int64 f;
QueryPerformanceFrequency( (LARGE_INTEGER *)&f );
printf("%20s Calls\tMean (secs)\tStdDev\n","Scope");
for( map < string, accumulator_set<__int64, stats<tag::variance(lazy)> > >::iterator p = myMap.begin();
p != myMap.end(); p++ )
{
float av = mean(p->second) / f;
float stdev = sqrt( ((double) variance(p->second)) ) / f;
printf("%20s %d\t%f\t%f\n",p->first.c_str(),
boost::accumulators::count(p->second), av, stdev);
}
}
void a()
{
cProfile profile("a");
Sleep ( rand() % 10 + 10 );
}
void b()
{
cProfile profile("b");
Sleep ( rand() % 20 + 5 );
}
int _tmain(int argc, _TCHAR* argv[])
{
for (int k=1;k<=100;k++) {
a();
b();
}
cProfile profile_report;
return 0;
}
产生
Scope Calls Mean (secs) StdDev
a 100 0.014928 0.002827
b 100 0.015254 0.005671
关于c++ - 如何分析对函数的每次调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1079008/