【问题标题】:OpenCL measure kernels timeOpenCL 测量内核时间
【发布时间】:2015-12-18 03:31:00
【问题描述】:

我有问题。我在循环中有两个内核,位于顶部。我想查看所有正在运行的内核的总时间,即使第一个内核将每秒运行例如 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);
            }
    }
}

【问题讨论】:

  • 为了清楚起见,您想要一个数字表示“运行所有这些内核总共花费了 T 秒”,还是您想要每个单独的内核调用的执行时间?

标签: opencl


【解决方案1】:

这部分取决于如何“安排”时间。

一些一般提示:

您必须通过在创建命令队列时传递 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),它等待给定的事件,然后计算事件持续时间,释放事件并返回计算的持续时间
  • 代码正在等待事件这一事实在某些情况下可能会影响运行时行为

最重要的是:

  • 如果您不是绝对需要这种“编程访问”,您应该考虑在分析器中简单地运行您的代码。这应该会为您提供所需的信息,即命令队列中每个内核所花费的时间。

【讨论】:

    猜你喜欢
    • 2014-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-13
    • 1970-01-01
    • 2021-03-03
    • 1970-01-01
    • 2017-03-08
    相关资源
    最近更新 更多