我已经使用OpenCL几个月了,最近遇到了一个有关我开发的特定程序中最大工作项数(全局大小)的问题。
首先,让我浏览一下工作尺寸清单:
好的,现在问题了。问题是,当且仅当工作项的数量(全局项大小)大于2 ^ 31时,我的一维内核才完成error code -36
(即CL_INVALID_COMMAND_QUEUE
)的执行(我添加了工作组大小,使其大于2 ^ 31,但仍是倍数)。现在,我运行程序时要做的第一件事是检查CL_DEVICE_ADDRESS_BITS
是否为64位。请参阅下面的内容以及我在程序开始时提取的一些更多信息:
Device [3]: GeForce GTX 980
Profile : OpenCL 1.2 CUDA
is available?: 1
Global mem : 4234280960 (4038 MB)
Local mem : 49152 (48 KB)
Compute units: 16
Max work group size: 1024
Work size items: (1024, 1024, 64)
Address space in bits: 64
如果您想知道,这是一个可计算许多小型作业的应用程序。我已经设计了一种解决方案来跳过此步骤,即为每个工作项分配更多的工作,以便减少工作项。但是,我对为什么会这样感兴趣。据我所知,它不应该发生,因为地址空间是64位。我还确保程序中的所有变量都是64位,并且不会以任何方式被截断。以防万一,变量是:
size_t global_item_size;
在执行过程中我还会打印以确保其包含适当的值:
fprintf(stdout, "Work items: %"PRIu64"\n", (uint64_t) global_item_size);
最后,内核在结构体内部以64位作为参数接收工作项的数量:
ulong t_work_items;
当地址空间为64位并且处理工作项数量(2 ^ 31 + WORK_GROUP_SIZE)的所有变量均为64位时,我无法想到会失败。 但是,我认为这是可能的。实际上,我无法从其他人(文档中也没有找到)执行过内核且工作项数量更多的引用,而没有失败。
尤其是,我不需要它,因为正如我所说,我可以增加每个工作项的工作量。但是我想根据三个值(每个工作项的作业大小和工作组大小)来衡量绩效,并发现了这一点。
感谢您的阅读!!
我还检查了CL_DEVICE_MAX_WORK_ITEM_SIZES
并得到了Max work item sizes: (1024,1024,64)
。但是,我认为这不是限制工作项数量的原因,因为根据文档OpenCL reference:
在global_work_size中指定的值不能超出sizeof(size_t)给将在其上排队执行内核的设备的范围。可以使用clGetDeviceInfo的OpenCL设备查询表中的CL_DEVICE_ADDRESS_BITS确定设备的sizeof(size_t)。例如,如果CL_DEVICE_ADDRESS_BITS = 32,即设备使用32位地址空间,则size_t是32位无符号整数,并且global_work_size值必须在1 .. 2 ^ 32-1范围内。一个CL_OUT_OF_RESOURCES错误。
由于我的地址空间是64位,所以没有出现CL_OUT_OF_RESOURCES
错误。怎么了?