为多个工作项计时时是否需要更多事件?
Do I need more events when timing multiple work-items?
如果我有多个工作项来执行一些内核代码,我是否需要有更多的事件来跟踪每个工作项的执行时间?
我有一些奇怪的结果,执行 1 个工作项大约需要 4 秒,执行 100 个工作项也需要大约 4 秒。我看不出这怎么可能,因为我的 Nvidia GeForce GT 525M 只有 2 个计算单元,每个计算单元有 48 个处理元素。这使我相信我在 clEnqueueNDRangeKernel 中作为参数列出的事件仅跟踪一个工作项。这是真的吗?如果是的话,我怎样才能让它跟踪所有的工作项目?
这是 Khronos 用户指南对 clEnqueueNDRangeKernel 中事件参数的描述:
event returns an event object that identifies this particular kernel execution instance
"this particular kernel execution instance"是什么意思?那不是一个单一的工作项目吗?
编辑:
相关主机代码:
static const size_t numberOfWorkItems = 48;
const size_t globalWorkSize[] = { numberOfWorkItems, 0, 0 };
cl_event events;
ret = clEnqueueNDRangeKernel(command_queue, kernel, 1, NULL, globalWorkSize, NULL, 0, NULL, &events);
ret = clEnqueueReadBuffer(command_queue, memobj, CL_TRUE, 0, sizeof(cl_mem), val, 0, NULL, NULL);
clWaitForEvents(1, &events);
cl_ulong time_start;
cl_ulong time_end;
clGetEventProfilingInfo(events, CL_PROFILING_COMMAND_QUEUED, sizeof(cl_ulong), &time_start, NULL);
clGetEventProfilingInfo(events, CL_PROFILING_COMMAND_END, sizeof(cl_ulong), &time_end, NULL);
double nanoSeconds = (double) (time_end - time_start);
printf("OpenCl Execution time is: %f milliseconds \n",nanoSeconds / 1000000.0);
printf("Result: %lu\n", val[0]);
内核代码:
kernel void parallel_operation(__global ulong *val) {
size_t i = get_global_id(0);
int n = 48;
local unsigned int result[48];
for (int z = 0; z < n; z++) {
result[z] = 0;
}
// here comes the long operation
for (ulong k = 0; k < 2000; k++) {
for (ulong j = 0; j < 10000; j++) {
result[i] += (j * 3) % 5;
}
}
barrier(CLK_LOCAL_MEM_FENCE);
if (i == 0) {
for (int z = 1; z < n; z++) {
result[0] += result[z];
}
*val = result[0];
}
}
您正在测量整个内核函数的执行时间。或者换句话说,第一个工作项开始和最后一个工作项完成之间的时间。据我所知,在 OpenCL 中无法测量单个工作项的执行时间。
如果我有多个工作项来执行一些内核代码,我是否需要有更多的事件来跟踪每个工作项的执行时间?
我有一些奇怪的结果,执行 1 个工作项大约需要 4 秒,执行 100 个工作项也需要大约 4 秒。我看不出这怎么可能,因为我的 Nvidia GeForce GT 525M 只有 2 个计算单元,每个计算单元有 48 个处理元素。这使我相信我在 clEnqueueNDRangeKernel 中作为参数列出的事件仅跟踪一个工作项。这是真的吗?如果是的话,我怎样才能让它跟踪所有的工作项目?
这是 Khronos 用户指南对 clEnqueueNDRangeKernel 中事件参数的描述:
event returns an event object that identifies this particular kernel execution instance
"this particular kernel execution instance"是什么意思?那不是一个单一的工作项目吗?
编辑: 相关主机代码:
static const size_t numberOfWorkItems = 48;
const size_t globalWorkSize[] = { numberOfWorkItems, 0, 0 };
cl_event events;
ret = clEnqueueNDRangeKernel(command_queue, kernel, 1, NULL, globalWorkSize, NULL, 0, NULL, &events);
ret = clEnqueueReadBuffer(command_queue, memobj, CL_TRUE, 0, sizeof(cl_mem), val, 0, NULL, NULL);
clWaitForEvents(1, &events);
cl_ulong time_start;
cl_ulong time_end;
clGetEventProfilingInfo(events, CL_PROFILING_COMMAND_QUEUED, sizeof(cl_ulong), &time_start, NULL);
clGetEventProfilingInfo(events, CL_PROFILING_COMMAND_END, sizeof(cl_ulong), &time_end, NULL);
double nanoSeconds = (double) (time_end - time_start);
printf("OpenCl Execution time is: %f milliseconds \n",nanoSeconds / 1000000.0);
printf("Result: %lu\n", val[0]);
内核代码:
kernel void parallel_operation(__global ulong *val) {
size_t i = get_global_id(0);
int n = 48;
local unsigned int result[48];
for (int z = 0; z < n; z++) {
result[z] = 0;
}
// here comes the long operation
for (ulong k = 0; k < 2000; k++) {
for (ulong j = 0; j < 10000; j++) {
result[i] += (j * 3) % 5;
}
}
barrier(CLK_LOCAL_MEM_FENCE);
if (i == 0) {
for (int z = 1; z < n; z++) {
result[0] += result[z];
}
*val = result[0];
}
}
您正在测量整个内核函数的执行时间。或者换句话说,第一个工作项开始和最后一个工作项完成之间的时间。据我所知,在 OpenCL 中无法测量单个工作项的执行时间。