OpenCL测量内核时间

时间:2014-04-24 14:41:26

标签: opencl

我有问题。我在循环中有两个内核,位于顶部。我希望看到所有正在运行的内核的总时间,即使第一个内核将运行例如每秒10次,例如5次。

非常感谢。

for (int arrayLength = minLengthArray; arrayLength <= N; arrayLength *= 2)
{
    int threadCount = 0;
    int batchSize = N / arrayLength;
    int  GroupCount = (batchSize * arrayLength) / SHARED_SIZE_LIMIT;
    size_t local = SHARED_SIZE_LIMIT / 2;
    size_t global = local * GroupCount;

    if (arrayLength <= SHARED_SIZE_LIMIT)
    {
        err = clEnqueueNDRangeKernel(commands, ddEvenMergeSortSharedKernel, 1, NULL, &global, &local, 0, NULL,  NULL);
    }
    else
    {
        clSetKernelArg(oddEvenMergeSortSharedKernel, 5, sizeof(unsigned int), &SHARED_SIZE_LIMIT);
        err = clEnqueueNDRangeKernel(commands, oddEvenMergeSortSharedKernel, 1, NULL, &global, &local, 0, NULL,  NULL);

        for (int size = 2 * SHARED_SIZE_LIMIT; size <= arrayLength; size <<= 1)
            for (unsigned stride = size / 2; stride > 0; stride >>= 1)
            {
                global = batchSize * arrayLength;
                local = 256;

                err = clEnqueueNDRangeKernel(commands, oddEvenMergeSortGlobalKernel, 1, NULL, &global, &local, 0, NULL,  NULL);
            }
    }
}

1 个答案:

答案 0 :(得分:3)

部分取决于如何制定&#34;安排&#34;时机。

一些一般提示:

您必须通过在创建命令队列时传递CL_QUEUE_PROFILING_ENABLE标志来为命令队列启用事件分析:

commands = clCreateCommandQueue(
    context, device, CL_QUEUE_PROFILING_ENABLE, &err);

在循环中,您必须为内核调用创建事件。这里有不同的选项:您可以收集内核调用的事件(在某些向量,列表或数组中),也可以单独执行每个事件的时间。基本方法如下,针对第一个内核(省略错误处理)

cl_event event0;  // creating an event variable for timing 
clEnqueueNDRangeKernel(commands, ddEvenMergeSortSharedKernel, 
    1, NULL, &global, &local, 0, NULL, &event0); // Pass in event here

clWaitForEvents (1, &event0); // Wait for the event

// Obtain the start- and end time for the event
unsigned long start = 0;
unsigned long end = 0;
clGetEventProfilingInfo(event0,CL_PROFILING_COMMAND_START,
    sizeof(cl_ulong),&start,NULL);       
clGetEventProfilingInfo(event0,CL_PROFILING_COMMAND_END,
    sizeof(cl_ulong),&end,NULL);

// Compute the duration in nanoseconds
unsigned long duration = end - start;

// Don't forget to release the vent
clReleaseEvent(event0);

然后可以相应地累积持续时间(以纳秒为单位)。相同的方案可以用于第二个内核。

但是,您应该考虑以下几点:

  • 涉及一些样板代码。也许你想把它提取成一个方便的方法,比如等待给定事件的duration = processEvent(event0),然后计算事件持续时间,释放事件并返回计算的持续时间
  • 代码等待事件的事实可能会影响某些情况下的运行时行为

最重要的是:

  • 如果您不完全需要这种&#34;编程访问&#34;,您应该考虑在分析器中运行您的代码。这应该为您提供所需的信息,即命令队列中每个内核花费的时间。