我可以依靠valgrind / callgrind的绝对成本来衡量和比较不同的实现吗?

时间:2012-12-18 12:06:20

标签: linux valgrind callgrind

现在我使用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%)

由于两种方法的整个过程是相同的,期望第三部分,如果第三部分的消耗时间百分比很小,我们可以预期运行程序的总时间也应该很小。但是,我们上面观察到的是矛盾的。我想知道我的分析有什么问题。谢谢!

1 个答案:

答案 0 :(得分:1)

shell有一个内置的time命令。如果您使用它,它将显示挂钟以及用户和系统时间。

linux> /bin/sh
$ time a.out
    0m1.01s real     0m0.00s user     0m0.00s system

如果您需要的分辨率高于0.01秒,则可以使用getrusagegettimeofday

在分析函数时,最好将检测放在尽可能靠近函数的位置。使用像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)