【问题标题】:OpenCL: Relationship between size of array and global size of work itemsOpenCL:数组大小与工作项全局大小之间的关系
【发布时间】:2020-10-29 00:42:22
【问题描述】:

任何人都知道 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* 的大小与工作项的全局大小之间存在直接关系?我这么说只是因为我看不到每个内核如何在数组的不同数据点上运行?

【问题讨论】:

    标签: arrays opencl


    【解决方案1】:

    看看内核是如何通过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);
    

    这里指定了工作项的数量,以及一些额外的参数,用于维度、偏移量和明确的工作组细分。但是,无论您指定多少工作项,即执行内核函数的实例,它们都将获得自己的全局和本地索引,您现在可以使用这些索引以任何有意义的方式访问数据适用于您的应用程序(并且不违反 OpenCL 编程模型的约束)。

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

    希望对您有所帮助。

    【讨论】:

    • 谢谢。更准确地说,我的问题是每个工作项的全局/索引 id 与用于遍历输入数据结构的索引相关的机制是哪种机制,在我的例子中是数组 A*?如果你能给我一些材料来阅读这方面的内容,那将对我有所帮助。无论如何感谢您的帮助!
    • 这种关系完全取决于您和您手头的问题。您从 OpenCL 获得的是您在 clEnqueueNDRangeKernel() 上指定的范围内的工作项的索引。如果您的内核将有两个参数global float* input 和global float* output,而您只是想复制数据,您将执行output[get_global_id(0)] = input[get_global_id(0)]; 并使用具有global_work_size[0] 的一维范围启动内核(参数是一个数组) 的输入/输出数组大小(元素计数)。
    • 我通常会向 OpenCL 入门的人推荐这个教程:handsonopencl.github.io
    猜你喜欢
    • 2016-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多