OpenCL:数组大小与工作项全局大小之间的关系

OpenCL: Relationship between size of array and global size of work items

任何人都知道 GPU 内核如何访问位于全局内存中的大型数据阵列的详细信息(并且由于某种原因我们不能只复制到共享内存)?假设我们有一个类型的内核:

kernel void doSomething(global A* s, global float* result)
{
    uint gidx = get_global_id(0);
   // some code here using the global index of the thread gidx...
}

我的理解 - 如果我错了请纠正我 - 是每个线程访问一个连续的元素 s[gidx] 并对其执行操作。这是否意味着全局数组 A* 的大小与工作项的全局大小之间存在直接关系?我这么说只是因为我看不到每个内核如何在数组的不同数据点上运行?

查看内核如何通过 clEnqueueNDRangeKernel 从主机代码启动:

cl_int clEnqueueNDRangeKernel(
    cl_command_queue command_queue,
    cl_kernel kernel,
    cl_uint work_dim,
    const size_t* global_work_offset,
    const size_t* global_work_size,   // number of work-items
    const size_t* local_work_size,
    cl_uint num_events_in_wait_list,
    const cl_event* event_wait_list,
    cl_event* event);

那里指定了 work-items 的数量,还有一些附加参数用于维度、偏移量和显式 sub-division 到 work-groups。但是无论您在此处指定什么,都将决定有多少 work-items,即执行了内核函数的实例,并且每个实例都将获得自己的全局和本地索引,您现在可以使用它们以任何方式访问数据对您的应用有意义(并且不违反 OpenCL 编程模型的约束)。

一个非常典型的模式是在要从某些输入生成的输出数据数组之间建立一对一的关系,并让每个 work-item 并行计算其中的一个元素。但是你也可以想出其他模式,例如从 work-items 开始少于数组元素,并让每个元素计算数组的范围,例如为特定硬件目标增加每个 work-item 的工作量。通常 work-item 范围以某种方式与输出数据范围相关联,因为所有 work-items 都可能并行执行,因此通常应写入 non-overlapping 部分内存。

希望对您有所帮助。