2012-05-10 23 views
0

Я пытаюсь измерить процессорное время следующего кода - struct timespec time1, time2, temp_time;Почему процессорное время отрицательное

  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 вызывается из разных фил следующим образом:

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

Вы значения wrapping: Если t2.tv_sec = t1.tv_sec + 1, но t2.tv_nsec

ответ

2

выглядит как использование переполнения unsigned long или лучше double для diff

+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 sys-заголовков (и glibc?) Предоставляют макросы для правильной обработки такого рода арифметики timespec, не так ли?

0

Одна из возможных проблем заключается в том, что формат printf предназначен для длинного знакового целочисленного значения (%ld), но параметр имеет двойной тип. Для исправления проблемы необходимо изменить %ld на номер %lf в строке формата.

0

Посмотрите на вашем заявлении для печати:

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

Второго параметр, который проходит двойной, но вы распечатывание этого значения с плавающей запятой в качестве длинного (% л.д.). Я подозреваю, что это половина вашей проблемы.

Это может генерировать лучшие результаты:

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); 
Смежные вопросы