2012-05-10 12 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

diff

+0

ええと、diffは長くて、printfを修正する必要があります... – Malkocoglu

0
のオーバーフローを使用 unsigned longまたはより良い doubleのように見えます

明らかな理由から、 '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 sysヘッダー(とglibc?)は、この種のtimespec算術を正しく処理するためのマクロを提供していますか?

0

考えられる問題の原因の1つは、printf形式が長い符号付き整数値(%ld)用であるが、パラメータにdouble型があることです。問題を解決するには、フォーマット文字列内で%ld%lfに変更する必要があります。あなたのprint文で

0

ルック:

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

あなたが渡す2番目のパラメータは、二重ですが、あなたが長い(%ldの)として、この浮動小数点値をプリントアウトしています。私はあなたの問題の半分だと思う。

これは、より良い結果を生成することがあります。

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

私も、keetyに同意あなたはおそらくunsigned型を使用するか、あなたはおそらく、ミリ秒単位の代わりに、ナノ秒単位で滞在して完全にオーバーフローの問題を避けることができます。ここでは、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); 
関連する問題