【问题标题】:Do I need more events when timing multiple work-items?为多个工作项计时时是否需要更多事件?
【发布时间】:2018-06-14 13:30:19
【问题描述】:

如果我有多个工作项来执行某些内核代码,是否需要更多事件来跟踪每个工作项的执行时间?

我有一些奇怪的结果,1 个工作项大约需要 4 秒来执行,100 个工作项也需要大约 4 秒来执行。我看不出这怎么可能,因为我的 Nvidia GeForce GT 525M 只有 2 个计算单元,每个单元有 48 个处理元件。这使我相信我在 clEnqueueNDRangeKernel 中作为参数列出的事件仅跟踪一个工作项。这是真的吗?如果是这样,我怎样才能让它跟踪所有工作项?

这是 Khronos 用户指南中关于 clEnqueueNDRangeKernel 中的事件参数的说明:

event 返回一个标识这个特定内核执行实例的事件对象

“这个特定的内核执行实例”是什么意思?那不是一个单独的工作项吗?

编辑: 相关主机代码:

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];
    }
}

【问题讨论】:

  • 如果使用 CL_PROFILING_COMMAND_START,结果会改变吗?
  • @Conradin 不,在这两种情况下仍然大约 4 秒。
  • 有趣。据我了解,执行时间不应该相同。您是否尝试过将工作项的数量增加到 100 个以上,以查看执行时间是否增加?另外,当您更改工作项的数量时,您是否更改了内核中的n
  • @Conradin 是的,我总是更改 n 以匹配工作项的数量。当我增加到 900 个工作项时,大约需要 5.5 秒。
  • 我猜这些时间来自于工作项在 GPU 上的调度方式。不幸的是,我不知道这是如何详细工作的。如果您想了解更多信息,我建议您使用不同的工作规模进行广泛的测试,也许您可​​以在某个时候找到一个模式。

标签: opencl nvidia gpgpu


【解决方案1】:

您正在测量整个内核函数的执行时间。或者换句话说,第一个工作项开始和最后一个工作项结束之间的时间。据我所知,在 OpenCL 中无法测量单个工作项的执行时间。

【讨论】:

  • 如果是这样,你知道我为什么会得到这些数字吗?我一直假设一个工作项将映射到一个处理元素,理论上可以有 48 个并发工作项,如果使用所有内核则为 96 个,但是当没有物理空间可做时,如何同时执行 100 个工作项是吗?
  • 如果您使用的工作项超出了硬件所能容纳的数量,它们将分块执行。例如,如果您有 100 个工作项,但只能容纳 48 个,则它们很可能分两组执行,每组 48 个,一组 4 个。
  • 那么执行 48+48+4 的时间不会至少是执行 48 的时间的两倍吗?
  • 这取决于每个工作项完成了多少工作。如果您使用 48 个工作项而不是 96 个来解决固定问题大小,那么 48 个工作项中的每一个都必须做两倍的工作,因此执行时间会更长。
  • 就我而言,所有工作项都在执行相同的操作。这不是现实生活中的场景,我只是想通过定时来弄清楚工作项如何映射到硬件。所以 48 个项目做同样的事情,96 个项目做同样的事情。为什么它们需要相同的时间?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-06-02
  • 1970-01-01
  • 2015-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-16
相关资源
最近更新 更多