opencl中的clock()

时间:2012-01-13 10:57:17

标签: cuda opencl gpu

我知道CUDA中有函数clock(),您可以在其中放入内核代码并查询GPU时间。但我想知道OpenCL中是否存在这样的事情?有没有办法在OpenCL中查询GPU时间? (我正在使用NVIDIA的工具包)。

5 个答案:

答案 0 :(得分:5)

没有OpenCL方法直接查询时钟周期。但是,OpenCL确实有一个分析机制,可以在计算设备上公开增量计数器。通过比较有序事件之间的差异,可以测量经过的时间。请参阅clGetEventProfilingInfo。

答案 1 :(得分:3)

仅为其他人寻求帮助:简要介绍使用OpenCL分析内核运行时

启用分析模式:

cmdQueue = clCreateCommandQueue(context, *devices, CL_QUEUE_PROFILING_ENABLE, &err);

分析内核:

cl_event prof_event; 
clEnqueueNDRangeKernel(cmdQueue, kernel, 1 , 0, globalWorkSize, NULL, 0, NULL, &prof_event);

在以下位置读取分析数据:

cl_ulong ev_start_time=(cl_ulong)0;     
cl_ulong ev_end_time=(cl_ulong)0;   

clFinish(cmdQueue);
err = clWaitForEvents(1, &prof_event);
err |= clGetEventProfilingInfo(prof_event, CL_PROFILING_COMMAND_START, sizeof(cl_ulong), &ev_start_time, NULL);
err |= clGetEventProfilingInfo(prof_event, CL_PROFILING_COMMAND_END, sizeof(cl_ulong), &ev_end_time, NULL);

计算内核执行时间:

float run_time_gpu = (float)(ev_end_time - ev_start_time)/1000; // in usec

尚无法对个别工作项目/工作单进行概要分析。 您可以设置globalWorkSize = localWorkSize进行性能分析。那你就只有一个工作组。

顺便说一句:对单个工作项(某些工作项)进行概要分析并不是很有帮助。只使用一些工作项,您将无法隐藏内存延迟和开销导致无意义的测量。

答案 2 :(得分:3)

试试这个(当然只适用于NVidia OpenCL):

uint clock_time()
{
    uint clock_time;
    asm("mov.u32 %0, %%clock;" : "=r"(clock_time));
    return clock_time;
}

答案 3 :(得分:2)

NVIDIA OpenCL SDK有一个示例Using Inline PTX with OpenCL。时钟寄存器可通过内联PTX作为特殊寄存器%时钟访问。 PTX: Parallel Thread Execution ISA手册中描述了%clock。您应该能够用%% clock替换%% laneid。

我从未使用OpenCL对此进行测试,但在CUDA中使用它。

请注意,编译器可能会重新排序或删除读取的寄存器。

答案 4 :(得分:1)

在NVIDIA上,您可以使用以下内容:

having

typedef unsigned long uint64_t; // if you haven't done so earlier inline uint64_t n_nv_Clock() { uint64_t n_clock; asm volatile("mov.u64 %0, %%clock64;" : "=l" (n_clock)); // make sure the compiler will not reorder this return n_clock; } 关键字告诉优化器您确实是指它并且不希望它被移动/优化掉。这是在PTX和{}}中执行此操作的标准方法。在gcc

请注意,这会返回时钟,而不是纳秒。您需要查询设备时钟频率(使用volatile)。另请注意,在较旧的设备上有两个频率(如果计算与此情况无关的内存频率,则为三个):设备时钟和着色器时钟。你想要的是着色器时钟。

使用64位版本的寄存器,您不必担心溢出,因为它通常需要数百年。另一方面,32位版本可能会经常溢出(您仍然可以恢复结果 - 除非它溢出两次)。