0

现在我正在使用 valgrind/callgrind 来衡量和比较不同的算法实现。假设一个算法有两种实现,处理链如下:

void main()
{
    //Procedure 1
    fun1();
    //Procedure 2
    fun2();
    //Procedure 3
    Algorithm_imp_1();  //Algorithm_imp_2(); 
   //Procedure 4
    fun4();
}

这两种实现的区别在于第三个过程,其中执行了两种不同的算法实现。为了看看哪个实现更好,我现在在 kachegrind 的帮助下使用 valgrind/callgrind。

据我所知,ifAlgorithm_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%)

由于这两种方法的整个过程都是一样的,除了第三部分,如果第三部分消耗的时间百分比很小,我们可以预计运行程序的总时间也应该很小。然而,我们在上面观察到的是矛盾的。我想知道我的分析有什么问题。谢谢!

4

1 回答 1

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)
于 2012-12-19T22:23:16.057 回答