1

GPUで計算を実行するcudaコードがあります。私は clock(); を使用しています。タイミングを知るために

私のコード構造は

__global__ static void sum(){

// calculates sum 
}

extern "C"
int run_kernel(int array[],int nelements){
 clock_t start, end;
  start = clock();
  //perform operation on gpu - call sum
 end = clock();
 double elapsed_time = ((double) (end - start)) / CLOCKS_PER_SEC;
 printf("time required : %lf", elapsed_time);
}

しかし、時刻は常に 0.0000 印刷の開始時刻と終了時刻を確認しました。開始にはある程度の値がありますが、終了時間は常にゼロです。

何が原因でしょうか?時間を測定するための代替手段。

どんな助けでも大歓迎です。

ありがとう

4

4 に答える 4

7

ここには 2 つの問題があります。

  1. 関数のclock()分解能が低すぎて、計測しようとしているイベントの期間を測定できません
  2. CUDA カーネルの起動は非同期操作であるため、時間はほとんどかかりません (正常なプラットフォームでは通常 10 ~ 20 マイクロ秒)。同期 CUDA API 呼び出しを使用して、カーネルの実行が終了するまでホスト CPU を強制的にブロックしない限り、実行時間を測定することはできません。

CUDA には独自の高精度のタイミング API があり、GPU で実行される操作のタイミングを計るのに推奨される方法です。それを使用するコードは次のようになります。

int run_kernel(int array[],int nelements){

    cudaEvent_t start,stop;
    cudaEventCreate(&start);
    cudaEventCreate(&stop);

    cudaEventRecord(start, 0);

    //
    //perform operation on gpu - call sum
    //

    cudaEventRecord(stop, 0); 
    cudaEventSynchronize(stop); 
    float elapsedTime; 
    cudaEventElapsedTime(&elapsedTime, start, stop); 
    printf("time required : %f", elapsed_time); 

    cudaEventDestroy(start);
    cudaEventDestroy(stop);
}
于 2012-04-30T06:19:39.567 に答える
5

clockCUDAカーネルの起動のタイミングに使用しないでください。を使用しcudaEventElapsedTimeます。カーネルの時間を計測するのに十分な精度があったとしてもclock(そうではありません)、カーネルの起動は非同期です。つまり、カーネルが完了する前に、制御フローが呼び出し元の関数に戻ります。

方法は次のとおりです。

void run_kernel(...)
{
  // create "events" which record the start & finish of the kernel of interest
  cudaEvent_t start, end;
  cudaEventCreate(&start);
  cudaEventCreate(&end):

  // record the start of the kernel
  cudaEventRecord(start);

  // perform operation on gpu - call sum
  sum<<<...>>>(...);

  // record the end of the kernel
  cudaEventRecord(end);

  // get elapsed time. Note that this call blocks
  // until the kernel is complete
  float ms;
  cudaEventElapsedTime(&ms, start, end);

  printf("time required : %f milliseconds", ms);

  cudaEventDestroy(start);
  cudaEventDestroy(end);
}
于 2012-04-30T06:17:02.277 に答える
0

最近では、経過時間を高解像度で測定するためにclock_gettime()を使用する必要があると思います。CLOCK_MONOTONIC私のコンピューターの解像度は 1ns で、これで十分です。

次のように使用できます

#include <time.h>
...

struct timespec start, end, res;

clock_getres(CLOCK_MONOTONIC, &res);
/* exact format string depends on your system, on mine time_t is long */
printf("Resolution is %ld s, %ld ns\n" res.tv_sec, res.tv_nsec);

clock_gettime(CLOCK_MONOTONIC, &start);
/* whatever */
clock_gettime(CLOCK_MONOTONIC, &end);

でコンパイル-lrt

編集:私はこれについて間違ったアプローチをとったようです。明らかに、それが必要な場合はCUDAタイミングを使用する必要があります。システムの時間を計った質問の行に従いました。

于 2012-04-30T06:11:41.123 に答える
0

cuda カーネルの起動は非同期であるため、カーネルの後に cudaThreadSynchronize() を追加する必要があります。

于 2012-04-30T12:56:32.370 に答える