5

私は複数のカーネルを持っており、それらは次のように順番に起動されます。

        clEnqueueNDRangeKernel(..., kernel1, ...);
        clEnqueueNDRangeKernel(..., kernel2, ...);
        clEnqueueNDRangeKernel(..., kernel3, ...);

また、複数のカーネルが1つのグローバルバッファを共有します。

ここで、すべてのカーネル実行のプロファイルを作成し、それらを合計して、clEnqueueNDRangeKernelの後にコードブロックを追加することにより、合計実行時間をカウントします。

        clFinish(cmdQueue);
        status = clGetEventProfilingInfo(...,&starttime,...);
        clGetEventProfilingInfo(...,&endtime,...);
        time_spent = endtime - starttime;

私の質問は、1つのclFinishで3つのカーネルをすべて一緒にプロファイリングする方法ですか?(最後のカーネル起動後に1つのclFinish()を追加するようなものです)。

はい、すべてのclEnqueueNDRangeKernelに異なるタイムイベントを与え、大きな負の数を取得します。詳細情報:

clEnqueueNDRangeKernel(cmdQueue,...,&timing_event1);
clFinish(cmdQueue);
clGetEventProfilingInfo(timing_event1,CL_PROFILING_COMMAND_START,sizeof(cl_ulong),&starttime1,NULL);
clGetEventProfilingInfo(timing_event1,CL_PROFILING_COMMAND_END,sizeof(cl_ulong),&endtime1,NULL);
time_spent1 = endtime1 - starttime1;

clEnqueueNDRangeKernel(cmdQueue,...,&timing_event2);
clFinish(cmdQueue);
clGetEventProfilingInfo(timing_event2,CL_PROFILING_COMMAND_START,sizeof(cl_ulong),&starttime2,NULL);
clGetEventProfilingInfo(timing_event2,CL_PROFILING_COMMAND_END,sizeof(cl_ulong),&endtime2,NULL);
time_spent2 = endtime2 - starttime2;

clEnqueueNDRangeKernel(cmdQueue,...,&timing_event3);
clFinish(cmdQueue);
clGetEventProfilingInfo(timing_event3,CL_PROFILING_COMMAND_START,sizeof(cl_ulong),&starttime3,NULL);
clGetEventProfilingInfo(timing_event3,CL_PROFILING_COMMAND_END,sizeof(cl_ulong),&endtime3,NULL);
time_spent3 = endtime3 - starttime3;

time_spent_all_0 = time_spent1 + time_spent2 + time_spent3;
time_spent_all_1 = endtime3 - starttime1;

すべてのclFinishがある場合、すべてのプロファイリング値は妥当ですが、time_spent_all_1はtime_spent_all_0の約2倍です。最後のclFinishを除くすべてのclFinishを削除すると、すべてのプロファイリング値が妥当ではなくなります。

私が望む結果を得たEricBainvilleに感謝します:1つのclFinishによって複数のclEnqueueNDRangeKernelをプロファイリングします。以下は私が使用する最終的なコードです:

clEnqueueNDRangeKernel(cmdQueue,...,&timing_event1);
clEnqueueNDRangeKernel(cmdQueue,...,&timing_event2);
clEnqueueNDRangeKernel(cmdQueue,...,&timing_event3);
clFinish(cmdQueue);

clGetEventProfilingInfo(timing_event1,CL_PROFILING_COMMAND_START,sizeof(cl_ulong),&starttime,NULL);
clGetEventProfilingInfo(timing_event3,CL_PROFILING_COMMAND_END,sizeof(cl_ulong),&endtime,NULL);
time_spent = endtime - starttime;
4

1 に答える 1

7

それぞれclEnqueueNDRangeKernelが独自のものを作成します。cl_event呼び出しの最後の引数はcl_event;へのポインターです。この最後の引数が0でない場合、新しいイベントが作成されます。

コマンドが完了した後、関連するイベントに開始/終了プロファイリング情報を照会できます。このイベントは、使用後に解放する必要があります(call clReleaseEvent)。

clFinishエンキューされたすべてのコマンドが完了するまでブロックします。

を呼び出す必要があるのは1回だけclFinishで、すべてのイベントのプロファイリング情報を照会できます。

于 2012-07-06T16:41:14.720 に答える