2014-05-14 7 views
0

clock_gettime()을 사용하여 코드 조각 (부동 소수점 곱셈)의 시간을 계산하려고합니다. 무작위로 100,000 개의 부동 소수점 10 개 배열을 생성 한 다음 한 번에 10 개를 모두 함께 곱합니다. 내가 원하는 것은 10 개의 부동 소수점 곱셈을 수행하는 데 걸리는 시간을 측정 한 다음 그 시간 값을 총 시간에 더한 다음 끝에 모두 출력하는 것입니다.C에서 clock_gettime을 사용한 타이밍 부동 소수점 계산, 시간이 계속 변경됩니까?

나는 그것이 모두 작동한다고 생각했지만 while 루프에서 내 printf() 문을 제거하면 28125692에서 17490394 나노초까지 시간이 줄어든다는 것을 발견했습니다! 이것은 일어나서는 안됩니다. 부동 소수점 곱셈의 시작과 끝 부분에서 clock_gettime() 호출을 배치 했으므로 이론적으로 printf() 문이 경과 시간에 영향을 미치지 않아야합니다!

아이디어가 있으십니까? 고맙습니다.

#include <stdio.h> 
#include <unistd.h> 
#include <stdlib.h> 
#include <time.h> 

int main(int argc, char *argv[]) 
{ 
    int i; 
    int j; 
    float alpha[100000]; 
    float bravo[100000]; 
    float charlie[100000]; 
    float delta[100000]; 
    float echo[100000]; 
    float foxtrot[100000]; 
    float golf[100000]; 
    float hotel[100000]; 
    float india[100000]; 
    float juliet[100000]; 
    float max; 
    long long num_calcs; 
    struct timespec start_time; 
    struct timespec end_time; 
    int diff_seconds; 
    long diff_nanoseconds; 
    long long total_calcs; 
    long long total_seconds; 
    long long total_nanoseconds; 

    num_calcs = 100000; 

    max = 1000.0; 

    printf("\n%lld floating point calculations requested.", num_calcs); 
    printf("\nGenerating random floating point values..."); 

    //initialize random seed 
    srand((unsigned int)time(NULL)); 

    //generate random floating point values 
    for (i = 0; i < 100000; i++) 
    { 
     alpha[i] = ((float) rand())/((float) (RAND_MAX)) * max; 
     bravo[i] = ((float) rand())/((float) (RAND_MAX)) * max; 
     charlie[i] = ((float) rand())/((float) (RAND_MAX)) * max; 
     delta[i] = ((float) rand())/((float) (RAND_MAX)) * max; 
     echo[i] = ((float) rand())/((float) (RAND_MAX)) * max; 
     foxtrot[i] = ((float) rand())/((float) (RAND_MAX)) * max; 
     golf[i] = ((float) rand())/((float) (RAND_MAX)) * max; 
     hotel[i] = ((float) rand())/((float) (RAND_MAX)) * max; 
     india[i] = ((float) rand())/((float) (RAND_MAX)) * max; 
     juliet[i] = ((float) rand())/((float) (RAND_MAX)) * max; 
    } 
    printf("done!"); 

    printf("\nRunning %lld floating point multiplications...", num_calcs); 

    //run calculations 
    i = 0; 
    total_calcs = 0; 
    total_seconds = 0; 
    total_nanoseconds = 0; 

    while (total_calcs < num_calcs) 
    { 
     printf("\n\nRunning 10 calculations..."); 
     //do 10 multiplications 
     //start the timer 
     if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start_time) < 0) 
     { 
      printf("\nclock_gettime for start_time failed, exiting..."); 
      return -1; 
     } 
     alpha[i] * bravo[i] * charlie[i] * delta[i] * echo[i] * 
     foxtrot[i] * golf[i] * hotel[i] * india[i] * juliet[i]; 
     //stop the timer 
     if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end_time) < 0) 
     { 
      printf("\nclock_gettime for end_time failed, exiting..."); 
      return -1; 
     } 
     printf("done!"); 
     total_calcs = total_calcs + 10; //increase total calculations 
     i++;    //increment array index 

     //show timing statistics 
     printf("\nSTART TIME tv_sec: %d", (int) start_time.tv_sec); 
     printf("\nSTART TIME tv_nsec: %ld", start_time.tv_nsec); 
     printf("\nEND TIME tv_sec: %d", (int) end_time.tv_sec); 
     printf("\nEND TIME tv_nsec: %ld", end_time.tv_nsec); 

     //calculate time it took to run 10 floating point caculcations 
     if ((end_time.tv_nsec - start_time.tv_nsec) < 0) 
     { 
      diff_seconds = end_time.tv_sec - start_time.tv_sec - 1; 
      diff_nanoseconds = 1000000000 + end_time.tv_nsec - start_time.tv_nsec; 
     } 
     else 
     { 
      diff_seconds = end_time.tv_sec - start_time.tv_sec; 
      diff_nanoseconds = end_time.tv_nsec - start_time.tv_nsec; 
     } 

     //add elapsed time for the last 10 calculations to total elapsed time 
     total_seconds = total_seconds + diff_seconds; 
     total_nanoseconds = total_nanoseconds + diff_nanoseconds; 

     printf("\nPerformed 10 floating point multiplications in %d seconds and %ld nanoseconds.", diff_seconds, diff_nanoseconds); 
     printf("\nPerformed %lld floating point multiplications in %lld seconds and %lld nanoseconds.", total_calcs, total_seconds, total_nanoseconds); 
    } 
    printf("done!"); 

    printf("\nPerformed %lld floating point multiplications in %lld seconds and %lld nanoseconds.\n", total_calcs, total_seconds, total_nanoseconds); 

    return 0; 
} 
+1

'alpha [i] * bravo [i] * charlie [i] * delta [i] * echo [i] * foxtrot [i] * golf [i] * hotel [i] * india [i] * juliet [i];'는 아무 작업도하지 않으며 최적화 컴파일러는 실행 파일에서이를 생략합니다. – pmg

+0

'for '의'printf' 문이 타이밍에 맞지 않는 코드가 성능에 영향을 줄 수있는 데에는 여러 가지 이유가 있습니다. 캐시 미스가 추가로 발생할 가능성이 큽니다. – SJuan76

+2

나노초의 양은 매우 정확합니다. 그것들은 각 구현을 한 번 실행 한 결과입니까? 28 ms와 17 ms 사이의 차이에 대해 이야기 할 때 CPU의 약간 다른 작업량이나 캐시 상태로 인해 쉽게 발생할 수 있습니다. 하나의 구현이 실제로 다른 것보다 느리다는 것을 결정하기 전에 수백 개의 테스트를 실행하고 평균해야합니다. – Daniel

답변

0

alpha[i] * bravo[i] * charlie[i] * delta[i] * echo[i] * 
    foxtrot[i] * golf[i] * hotel[i] * india[i] * juliet[i]; 

은 no-op입니다. 최적화 컴파일러는이를 실행 파일에서 생략합니다.

다른 변수에 결과를 추가하고 프로그램 끝에이 합계를 인쇄 해보십시오.