2012-12-18 59 views
0

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

因爲對於這兩種方法的整個過程都是一樣的預期。第三部分,如果第三部分所消耗的時間比例很小,我們可以期待運行程序的總時間也應該很小。但是,我們上面看到的是矛盾的。我想知道我的分析有什麼問題。謝謝!

+0

如果您使用Valgrind多次運行程序,您是否總能得到相同的數字? –

+0

謝謝,我已經檢查過。我發現,對於示例程序,我運行了多次callgrind,可以獲得相似或包含編號。 – feelfree

+0

我想你需要顯示其他部分的時間,因爲正如你所指出的那樣,即使唯一改變的部分要小得多,你也會看到30%的增加。或者將main()中的所有內容放在一個循環中進行一百萬次迭代,以清除任何隨機小波動。 –

回答

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) 
+0

謝謝,它有幫助。 – feelfree

相關問題