2016-01-06 118 views
0

我是OpenCL的新手,我试图了解由Apple编写的示例程序here计算适当数量的工作组及其大小OpenCL

该程序的目标是计算输入数组的每个元素的平方,并将结果写入新数组。

您可以看到输入数组的维数为1024.工作组的数量为1024,每个组的大小为最大值CL_KERNEL_WORK_GROUP_SIZE。

任何人都可以解释我如果在内核中没有get_local_id()调用,在每个工作组中使用如此多的工作项目有什么意义?他们可以使用1作为每个工作组的大小吗?会有什么区别?

谢谢。

一些代码来证明这一点:

// Get the maximum work group size for executing the kernel on the device 
    // 
    err = clGetKernelWorkGroupInfo(kernel, device_id, CL_KERNEL_WORK_GROUP_SIZE, sizeof(local), &local, NULL); 


    // Execute the kernel over the entire range of our 1d input data set 
    // using the maximum number of work group items for this device 
    // 
    global = count; 
    err = clEnqueueNDRangeKernel(commands, kernel, 1, NULL, &global, &local, 0, NULL, NULL); 
+0

这不是CUDA,尺寸不是本地*全球,只是全球。全局大小是重要的,内核代码运行那么多次。只有当您想分享运行项目的信息并且必须划分全局大小时,本地大小才有用。例如,在项目0-1023之间共享一些数据。如果您根本不共享数据,那么大小并不重要,但由于开销减少和设备占用率增加,因此较大的大小是首选。 – DarkZeros

+0

@DarkZeros好吧,我知道了,在这种情况下全局大小很重要,所以clEnqueueNDRangeKernel调用中的local_work_size可以是1或NULL,实际上什么都不会改变,对吧? – Matt

+1

是的,它。这就是OpenCL允许本地大小为NULL的原因,因此驱动程序会选择它认为最适合性能的大小。 – DarkZeros

回答

1

你的全局工作大小在本地工作的小块(理论上)执行的,如果你设置1为当地的工作组大小,那么它会执行每个本地工作组只有1个线程。在GPU上,工作组匹配计算单位 - 如果您的工作组大小为1,则您的1个线程可能占用整个计算单位。这是真的,真的非常慢

+0

因此,在每个工作组上使用1个工作项执行GPU上的代码比在CPU上执行相同代码的速度更快,但您仍然可以通过在工作组中完成更多工作来增加工作项的数量。它是否正确? – Matt

+0

重点是:如果我通过苹果增加了示例中工作项的数量,我将无法获得效率更好的结果,因为我没有使用本地内存。对? – Matt

+1

每个工作组的1个工作项可能比使用CPU慢。 GPU有32个计算核心,所以每个工作组1个工作项可能意味着只有32个“线程”一次运行,这非常缓慢。增加工作组大小将大大提高性能--gpus使用每个工作组线程来运行wave,这将填充GPU上的SIMD资源,并允许您通过合并访问获取内存。如果你只使用每个内核1个线程,你会大大利用这些资源 –