现在我使用valgrind / callgrind来测量和比较不同的算法实现。假设算法有两种实现方式,处理链如下:
void main()
{
//Procedure 1
fun1();
//Procedure 2
fun2();
//Procedure 3
Algorithm_imp_1(); //Algorithm_imp_2();
//Procedure 4
fun4();
}
这两个实现之间的区别在于第三个过程,其中执行了两个不同的算法实现。为了看看哪个实现更好,我现在在kachegrind的帮助下使用valgrind / callgrind。
据我所知,如果Algorithm_imp_1()
比Algorithm_imp_2()
效率更高,则有两个指标:一个是用于运行程序的绝对时间,另一个是百分比第三个程序所用的时间应该更小。但是,我用valgrind获得的内容非常令人困惑:
Method 1 whole procedure: overall circle 106858896849
Algorithm_imp_1(): circle 2971828457(3.03%)
Method 2 whole procedure: overall circle 137889090577
Algorithm_imp_2(): circle 351826053(0.26%)
由于两种方法的整个过程是相同的,期望第三部分,如果第三部分的消耗时间百分比很小,我们可以预期运行程序的总时间也应该很小。但是,我们上面观察到的是矛盾的。我想知道我的分析有什么问题。谢谢!
答案 0 :(得分:1)
shell有一个内置的time
命令。如果您使用它,它将显示挂钟以及用户和系统时间。
linux> /bin/sh
$ time a.out
0m1.01s real 0m0.00s user 0m0.00s system
如果您需要的分辨率高于0.01秒,则可以使用getrusage
和gettimeofday
。
在分析函数时,最好将检测放在尽可能靠近函数的位置。使用像valgrind这样的东西很可能掩盖了函数内发生的事情。
测量的信噪比必须很高才有用。
linux> cat a.c
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/resource.h>
/*
* Time elapsed in milli-seconds. Tweak this to get micro-seconds.
*/
int
time_diff(struct timeval *t2, struct timeval *t1)
{
int r;
r = (t2->tv_sec - t1->tv_sec)*1000 + t2->tv_usec/1000 - t1->tv_usec/1000;
return(r);
}
int
main()
{
struct rusage r1, r2;
struct timeval t1, t2;
(void)gettimeofday(&t1, 0);
(void)getrusage(RUSAGE_SELF, &r1);
sleep(1); /* Function to be profiled. */
(void)getrusage(RUSAGE_SELF, &r2);
(void)gettimeofday(&t2, 0);
printf("real = %d (ms), user = %d (ms), system = %d (ms)\n",
time_diff(&t2, &t1),
time_diff(&r2.ru_utime, &r1.ru_utime),
time_diff(&r2.ru_stime, &r1.ru_stime));
return(0);
}
当您运行上述内容时,您应该看到类似于下面的内容。
linux> a.out
real = 1000 (ms), user = 0 (ms), system = 0 (ms)