我怎么知道内核是否同时执行?

时间:2012-08-01 16:53:06

标签: opencl

我有一个带有CC 3.0的GPU,所以它应该支持16个并发内核。我通过循环clEnqueueNDRangeKernel 10次启动10个内核。我怎么知道内核正在同时执行?

我想到的一种方法是获取NDRangeKernel语句之前和之后的时间。我可能必须使用事件以确保内核的执行已完成。但我仍然认为循环将按顺序启动内核。有人可以帮帮我..

3 个答案:

答案 0 :(得分:12)

要确定内核执行是否重叠,您必须对它们进行分析。这需要几个步骤:

1。创建命令队列

仅当使用属性CL_QUEUE_PROFILING_ENABLE

创建命令队列时,才会收集分析数据
cl_command_queue queues[10];
for (int i = 0; i < 10; ++i) {
  queues[i] = clCreateCommandQueue(context, device, CL_QUEUE_PROFILING_ENABLE,
                                   &errcode);
}

2。确保所有内核同时启动

您可以假设CPU按顺序对内核进行排队。但是,您可以创建单个用户事件并将其添加到所有内核的等待列表中。这会导致内核在用户事件完成之前不开始运行:

// Create the user event
cl_event user_event = clCreateUserEvent(context, &errcode);

// Reserve space for kernel events
cl_event kernel_events[10];

// Enqueue kernels
for (int i = 0; i < 10; ++i) {
  clEnqueueNDRangeKernel(queues[i], kernel, work_dim, global_work_offset,
                         global_work_size, 1, &user_event, &kernel_events[i]);
}

// Start all kernels by completing the user event
clSetUserEventStatus(user_event, CL_COMPLETE);

3。获取分析时间

最后,我们可以收集内核事件的时间信息:

// Block until all kernels have run to completion
clWaitForEvents(10, kernel_events);

for (int i = 0; i < 10; ++i) {
  cl_ulong start;
  clGetEventProfilingInfo(kernel_event[i], CL_PROFILING_COMMAND_START,
                          sizeof(start), &start, NULL);
  cl_ulong end;
  clGetEventProfilingInfo(kernel_event[i], CL_PROFILING_COMMAND_END,
                          sizeof(end), &end, NULL);
  printf("Event %d: start=%llu, end=%llu", i, start, end);
}

4。分析输出

现在您拥有所有内核运行的开始和结束时间,您可以检查重叠(手动或以编程方式)。输出单位是纳秒。但请注意,设备计时器仅精确到某个分辨率。您可以使用以下方式查询分辨率:

size_t resolution;
clGetDeviceInfo(device, CL_DEVICE_PROFILING_TIMER_RESOLUTION,
                sizeof(resolution), &resolution, NULL);

FWIW,我在带有CC 2.0(应该支持并发内核)的NVIDIA设备上尝试了这一点,并观察到内核是按顺序运行的。

答案 1 :(得分:1)

您可以使用C Framework for OpenCL来避免其他答案中建议的所有样板代码(顺便说一下这是正确的),这会大大简化此任务,并为您提供有关OpenCL事件的详细信息(内核执行,数据传输等),包括专用于重叠执行所述事件的表格和图表。

我开发了这个库,以便简化其他答案中描述的过程。您可以看到基本用法示例here

答案 2 :(得分:0)

是的,正如您所建议的那样,尝试使用事件,并分析所有QUEUED,SUBMIT,START,END值。这些应该是“设备时间”中的绝对值,您可以看到处理(START到END)是否与不同的内核重叠。