Advertisement
MasWag

PAPI_lowlevel_flops.c

Jun 22nd, 2015
1,107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.73 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4. #include <sys/time.h>
  5. #include <omp.h>
  6. #include "papi.h"
  7.  
  8. void
  9. LU (double * mat,int num);
  10.  
  11. #define SIZE 11
  12. double mat[(1 << SIZE) * (1 << SIZE)];
  13.  
  14. int
  15. main ()
  16. {
  17.   srand (time (NULL));
  18.   int i;
  19.   int EventSet = PAPI_NULL;
  20.  
  21.   // 諸々の初期化
  22.   if (PAPI_library_init(PAPI_VER_CURRENT) != PAPI_VER_CURRENT) {
  23.     fprintf(stderr, "PAPI library init error!\n");
  24.     exit(1);
  25.   }
  26.   if (PAPI_thread_init((unsigned long (*)(void))(omp_get_num_threads)) != PAPI_OK) {
  27.     fprintf(stderr, "PAPI thread init error.\n");
  28.     exit(1);
  29.   }
  30.  
  31.   if (PAPI_num_counters() < 2) {
  32.     fprintf(stderr, "No hardware counters here, or PAPI not supported.\n");
  33.     exit(1);
  34.   }
  35.   // 浮動小数点演算の回数を取得する
  36.   PAPI_create_eventset( &EventSet );
  37.   PAPI_add_event(EventSet, PAPI_FP_OPS);
  38.  
  39.   puts ("Size\tReal_Time\tProcess_Time\tFLPops\tMFlops");
  40.  
  41.   int nthreads;
  42. #pragma omp parallel
  43.   {
  44.     // 0番スレッドのときはスレッド数を取得する
  45.     if (omp_get_thread_num() == 0)
  46.       nthreads = omp_get_num_threads();
  47.   }
  48.  
  49.   for (i = 1;i <= SIZE; ++i)
  50.     {
  51.       float rtime,ptime,mflops;
  52.       long long flpops = 0;
  53.       int ret;
  54.       const int num = 1 << i;
  55.       int j;
  56.       // 適当に行列に要素を入れる
  57.       for (j = 0;j < num * num; ++j)
  58.         {
  59.           mat[j] = rand () / 1000.0;
  60.         }
  61.  
  62.       long long values[nthreads];
  63.       for (j = 0 ; j < nthreads;j++) {
  64.         values[j] = 0;
  65.       }
  66.      
  67.       struct timeval start,end;
  68.       long long v_start,v_end;
  69.       // 開始時間の取得
  70.       v_start = PAPI_get_virt_usec();
  71.       gettimeofday(&start, NULL);
  72.       // 命令数のカウントの開始
  73.       if ((ret = PAPI_start (EventSet)) != PAPI_OK) {
  74.         fprintf(stderr, "PAPI failed to start counters: %s\n", PAPI_strerror(ret));
  75.         exit(1);
  76.       }
  77. #pragma omp parallel
  78.       {
  79.         LU (mat,num);
  80.         // 命令数のカウントの終了
  81.         if ((ret = PAPI_stop (EventSet,values + omp_get_thread_num ())) != PAPI_OK) {
  82.           fprintf(stderr, "PAPI failed to read counters: %s\n", PAPI_strerror(ret));
  83.           exit(1);
  84.         }
  85.       }
  86.       // 終了時間の取得
  87.       gettimeofday(&end, NULL);
  88.       v_end = PAPI_get_virt_usec();
  89.       rtime = (end.tv_sec - start.tv_sec) + 0.000001 * (end.tv_usec - start.tv_usec);
  90.       ptime = (v_end - v_start) * 1.0e-6;
  91.  
  92.       // 各スレッドでの実行命令数を足す
  93.       flpops = 0;
  94.       for (j = 0 ; j < nthreads;j++) {
  95.         flpops += values[j];
  96.       }
  97.       // flopsの計算
  98.       mflops = flpops/ptime*1.0e-6;
  99.  
  100.       printf ("%d\t%f\t%f\t%lld\t%f\n",num,rtime,ptime,flpops,mflops);
  101.     }
  102.  
  103. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement