有关全球和当地工作规模的问题

通过NVIDIA论坛search,我发现了这些也是我感兴趣的问题 ,但在过去的四天左右,没有人回答过这些问题 。 你能帮我吗?

原创论坛post

深入研究OpenCL的阅读教程,有些事情对我来说还不清楚。 这里是关于本地和全球工作规模的一系列问题。

  1. global_work_size必须小于CL_DEVICE_MAX_WORK_ITEM_SIZES吗? 在我的机器上CL_DEVICE_MAX_WORK_ITEM_SIZES = CL_DEVICE_MAX_WORK_ITEM_SIZES

  2. CL_KERNEL_WORK_GROUP_SIZE work_group_size为所使用的内核build议的work_group_size

    1. 或者这是GPU允许的唯一work_group_size ? 在我的机器上CL_KERNEL_WORK_GROUP_SIZE = 512
  3. 我是否需要分成工作组,或者我只有一个,但不指定local_work_size

    1. 当我只有一个工作组时,我该注意些什么?
  4. CL_DEVICE_MAX_WORK_GROUP_SIZE是什么意思? 在我的机器上CL_DEVICE_MAX_WORK_GROUP_SIZE = CL_DEVICE_MAX_WORK_GROUP_SIZE

    1. 这是否意味着,我可以拥有一个与CL_DEVICE_MAX_WORK_ITEM_SIZES一样大的工作组?
  5. global_work_sizeCL_DEVICE_MAX_WORK_ITEM_SIZES的除数吗? 在我的代码global_work_size = 20。

一般来说,您可以selectglobal_work_size作为您想要的大小,而local_work_size则受底层设备/硬件的约束,因此所有查询结果都会告诉您local_work_size的可能维数,而不是global_work_size。 global_work_size的唯一约束是它必须是local_work_size的倍数(对于每个维度)。

工作组大小指定工作组的大小,因此如果CL_DEVICE_MAX_WORK_ITEM_SIZES是512,512,64,则意味着您的local_work_size不能大于512 ,x和y维度为64 ,z维度为64

但是,根据内核,本地组的大小也有一个限制。 这通过CL_KERNEL_WORK_GROUP_SIZE表示。 您的累积工作量(如所有维度的乘积,例如256如果您的本地语言大小为16,16,1)不得大于该数字。 这是由于有限的硬件资源需要在线程之间进行划分(根据您的查询结果,我假设您正在NVIDIA GPU上进行编程,所以线程使用的本地内存和寄存器数量将会限制线程的数量并行执行)。

CL_DEVICE_MAX_WORK_GROUP_SIZE以与CL_KERNEL_WORK_GROUP_SIZE相同的方式定义工作组的最大大小,但是专用于设备而不是内核(并且它应该是一个标量值(又名512 ))。

您可以select不指定local_work_group_size,在这种情况下,OpenCL实现将为您select本地工作组大小(所以它不能保证它只使用一个工作组)。 然而这通常是不可取的,因为你不知道你的工作是如何分成工作组的,而且也不能保证所选的工作组大小是最优的。

但是,您应该注意,仅使用一个工作组在性能方面通常不是一个好主意(如果不考虑性能,则为什么要使用OpenCL)。 一般来说,一个工作组必须在一个计算单元上执行,而大多数设备将有多个(现代CPU有2个或更多,每个核心一个,而现代GPU可以有20个或更多)。 此外,即使您的工作组在其上运行的一个计算单元也可能没有被充分使用,因为几个工作组可以在一个计算单元上以SMT风格执行。 要最佳地使用NVIDIA GPU,您需要在一个计算单元上执行768/1024/1536个线程(取决于代号G80 / GT200 / GF100),而我现在还不知道amd的数目,相同的数量,所以多一个工作组是很好的。 此外,对于GPU,通常build议拥有至less64个线程的工作组(每个工作组可以有32/64(nvidia / amd)可以划分的线程数),否则会再次降低性能(32/64是gpus上执行的最小格式,所以如果你在工作组中有更less的项目,它仍然会以32/64的线程执行,但是会丢弃未使用线程的结果)。