2012-05-10 123 views
0

我想測量以下代碼的CPU時間 - struct timespec time1,time2,temp_time;爲什麼CPU時間是負的

  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1); 

      long diff = 0; 

      for(int y=0; y<n; y++) { 

       for(int x=0; x<n; x++) { 

       float v = 0.0f; 

       for(int i=0; i<n; i++) 

        v += a[y * n + i] * b[i * n + x]; 

         c[y * n + x] = v; 

        } 

      } 
     clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2); 

     temp_time.tv_sec = time2.tv_sec - time1.tv_sec; 

     temp_time.tv_nsec = time2.tv_nsec - time1.tv_nsec; 

     diff = temp_time.tv_sec * 1000000000 + temp_time.tv_nsec; 

     printf("finished calculations using CPU in %ld ms \n", (double) diff/1000000); 

但是,當我增加n的值時,時間值是負值。 代碼打印n = 500的正確值,但打印負值爲n = 700 任何幫助,將不勝感激。

以下是完整的代碼結構 -

void run(float A[], float B[], float C[], int nelements){ 
    struct timespec time1, time2, temp_time; 

      clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1); 

      long diff = 0; 

      for(int y=0; y<nelements; y++) { 

       for(int x=0; x<nelements; x++) { 

       float v = 0.0f; 

       for(int i=0; i<nelements; i++) 

        v += A[y * nelements + i] * B[i * nelements + x]; 

         C[y * nelements + x] = v; 

        } 

      } 
     clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2); 

     temp_time.tv_sec = time2.tv_sec - time1.tv_sec; 

     temp_time.tv_nsec = time2.tv_nsec - time1.tv_nsec; 

     diff = temp_time.tv_sec * 1000000000 + temp_time.tv_nsec; 

     printf("finished calculations using CPU in %ld ms \n"(double) diff/1000000); 
} 

此功能abovr從不同FIL稱爲如下:

SIZE = 500; 

a = (float*)malloc(SIZE * SIZE * sizeof(float)); 

b = (float*)malloc(SIZE * SIZE * sizeof(float)); 

c = (float*)malloc(SIZE * SIZE * sizeof(float)); 

//initialize a &b 
run(&a[SIZE],&b[SIZE],&c[SIZE],SIZE); 
+0

你確定你的'a'和'b'陣列夠大嗎?你可能會把它們溢出來,隨意亂寫一些內存,包括你的time1值。 –

+0

你有沒有正確地爲'a [],b []和c []'分配內存?有時出版的作品會造成奇怪的問題。可能要爲''數組'使用'std :: vector <>''。 – Hindol

+1

你的值正在包裝:如果t2.tv_sec = t1.tv_sec + 1,但是t2.tv_nsec

回答

2

看起來像一個溢出使用unsigned long或更好doublediff

+0

是的,diff應該很長,printf應該被修正... – Malkocoglu

0

'tv_nsec'字段不應超過10^9(1000000000),原因很明顯:

if (time1.tv_nsec < time2.tv_nsec) 
{ 
    int adj = (time2.tv_nsec - time1.tv_nsec)/(1000000000) + 1; 

    time2.tv_nsec -= (1000000000) * adj; 
    time2.tv_sec += adj; 
} 

if (time1.tv_nsec - time2.tv_nsec > (1000000000)) 
{ 
    int adj = (time1.tv_nsec - time2.tv_nsec)/(1000000000); 

    time2.tv_nsec += (1000000000) * adj; 
    time2.tv_sec -= adj; 
} 

temp_time.tv_sec = time1.tv_sec - time2.tv_sec; 
temp_time.tv_nsec = time1.tv_nsec - time2.tv_nsec; 

diff = temp_time.tv_sec * (1000000000) + temp_time.tv_nsec; 

這段代碼可以簡化,因爲它沒有假設'tv_sec'字段的符號。大多數Linux系統頭文件(和glibc?)都提供了宏來處理這種timepec算術,對嗎?

0

可能的問題原因之一是,printf格式用於長符號整數值(%ld),但該參數具有雙重類型。要解決該問題,必須在格式字符串中更改%ld%lf

0

看看你的print語句:

printf("finished calculations using CPU in %ld ms \n", (double) diff/1000000); 

你傳遞的第二個參數是雙重的,但你要打印出這個浮點值作爲長(%LD)。我懷疑這是你的一半問題。

這可能會產生更好的效果:

printf("finished calculations using CPU in %f ms \n", diff/1000000.0); 

我也同意keety,你可能應該使用無符號類型或者你可能會因住在毫秒爲單位,而不是納秒完全避免溢出的問題。這就是爲什麼我堅持使用64位無符號整數,並保持在毫秒級。

unsigned long long diffMilliseconds; 

diffMilliseconds = (time2.tv_sec * 1000LL + time2.tv_nsec/1000000) - (time1.tv_sec * 1000LL + time1.tv_nsec/1000000); 

printf("finished calculations using CPU in %llu ms \n", diffMilliseconds); 
相關問題