2012-04-30 9 views
0

私はGPU上で計算を実行するCUDAコードを持っています。 私はclock()を使用しています。タイミングを見つけるためにクロックを使った計算時間は0になる - Linux

私のコードの構造は、

__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 です。 Startには値がありますが、終了時刻は常にゼロです。

考えられる原因は何ですか?時間を測定するための任意の選択肢。

ご協力いただければ幸いです。私はあなたが、最近の高解像度に経過時間を計測するCLOCK_MONOTONICclock_gettime()を使用すべきであると信じている

おかげ

+0

'elapsed_time'はゼロまたは' end'はゼロですか?私はCPUではなくGPUを使用しているので、CPU時間を測定してもGPU時間は得られません。 – devil

+2

おそらく、測定している時間がクロックの細かさよりも小さいでしょうか? start = clock()とend = clock()の間でsleep(1)を一時的に叩いて、ゼロ以外の結果が得られたかどうか確認してください。 –

+2

この質問と同じ理由があるかもしれません:http://stackoverflow.com/q/2134363/10077 –

答えて

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); 
} 
0

。私のコンピュータ上では解像度は1nsで十分です。

あなたは-lrt

編集で

#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); 

コンパイルのようにそれを使用することができます:私は、何が必要であれば、明らかにあなたはCUDAのタイミングを使用する必要があり、私はこれで間違ったアプローチを取っていることがわかります。私はシステムのタイミングを決めたあなたの質問の行に従った。

5

CUDAカーネルの起動には、clockを使用しないでください。 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); 
} 
0

CUDAカーネルの起動は非同期なので、あなたは、カーネルの後cudaThreadSynchronize()を追加する必要があります。それを使用するコードは次のようになります