通过NVIDIA论坛搜索我发现these questions,我也感兴趣,但在过去四天左右没有人回答过它们。你能帮忙吗?
深入研究OpenCL阅读教程有些事情对我来说还不清楚。以下是关于本地和全球工作规模的问题集。
global_work_size
必须小于CL_DEVICE_MAX_WORK_ITEM_SIZES
吗? 在我的机器上CL_DEVICE_MAX_WORK_ITEM_SIZES
= 512,512,64。对于使用过的内核,
CL_KERNEL_WORK_GROUP_SIZE
是推荐的work_group_size
吗?
- 或者这是GPU允许的唯一
work_group_size
? 在我的机器上CL_KERNEL_WORK_GROUP_SIZE
= 512我是否需要分成工作组,或者我只能有一个,但不能指定
local_work_size
?
- 当我只有一个工作组时,我需要注意什么?
CL_DEVICE_MAX_WORK_GROUP_SIZE
是什么意思? 在我的机器上CL_DEVICE_MAX_WORK_GROUP_SIZE
= 512,512,64
- 这是否意味着,我可以拥有一个与
CL_DEVICE_MAX_WORK_ITEM_SIZES
一样大的工作组?- 中 醇>
global_work_size
是CL_DEVICE_MAX_WORK_ITEM_SIZES
的除数吗? 在我的代码global_work_size
= 20。
答案 0 :(得分:70)
通常,您可以根据需要选择global_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
1}}用于z维度。
但是,根据内核的不同,本地组大小也会受到限制。这通过CL_KERNEL_WORK_GROUP_SIZE
表达。您的累积workgoupsize(如所有维度的产品,例如256
,如果您的本地化大小为16, 16, 1
),则不得大于该数字。这是由于在线程之间划分的硬件资源有限(从您的查询结果我假设您在NVIDIA GPU上进行编程,因此线程使用的本地内存和寄存器数量将限制可以使用的线程数量)并行执行)。
CL_DEVICE_MAX_WORK_GROUP_SIZE
以与CL_KERNEL_WORK_GROUP_SIZE
相同的方式定义工作组的最大大小,但是特定于设备而不是内核(它应该是标量值,也就是512
)
您可以选择不指定local_work_group_size,在这种情况下,OpenCL实现将为您选择本地工作组大小(因此它不能保证它只使用一个工作组)。但是,这通常是不可取的,因为您不知道您的工作如何划分为工作组,而且不能保证所选择的工作组大小是最佳的。
但是,您应该注意,只使用一个工作组在性能方面通常不是一个好主意(如果性能不是问题,为什么要使用OpenCL)。通常,工作组必须在一个计算单元上执行,而大多数设备将具有多个(现代CPU具有2个或更多,每个核心一个,而现代GPU可以具有20个或更多)。此外,即使您的工作组执行的一个计算单元也可能无法完全使用,因为多个工作组可以在SMT样式的一个计算单元上执行。为了最佳地使用NVIDIA GPU,您需要在一个计算单元上执行768/1024/1536个线程(取决于生成,意味着G80 / GT200 / GF100),而我现在还不知道amd的数字,它们位于相同的幅度,所以有一个以上的工作组是好的。此外,对于GPU,通常建议工作组至少有64个线程(以及每个工作组可以被32/64(nvidia / amd)整除的线程数),否则你将再次降低性能(32/64是在gpus上执行的最小粒度,因此如果工作组中的项目较少,它仍将作为32/64线程执行,但会丢弃未使用线程的结果。“