我正在尝试在资源较少的嵌入式 GPU 上运行一些为桌面显卡编写的 OpenCL 内核。特别是,桌面版本假设始终支持至少 256 个工作组大小,但基于 Mali T628 ARM 的 GPU 仅保证 64+ 工作组大小。
事实上,一些内核报告CL_KERNEL_WORK_GROUP_SIZE
只有64个,我不明白为什么。我检查了CL_KERNEL_LOCAL_MEM_SIZE
对于有问题的内核,它CL_DEVICE_LOCAL_MEM_SIZE是 32 KiB,所以我想我可以排除__local
贮存。
还有哪些其他因素(例如寄存器/__private
内存?)导致低CL_KERNEL_WORK_GROUP_SIZE
,以及如何检查使用情况?我对程序化的内省持开放态度(例如clGetKernelWorkGroupInfo()
我已经做了一些),以及我可能不知道的任何开发工具。
EDIT:
这些内核是 OpenCV 的 OpenCL v2.4 模块的一部分。特别是,内核icvCalcOrientation
in surf.cl https://github.com/Itseez/opencv/blob/2.4/modules/nonfree/src/opencl/surf.cl。代码相当复杂,并且设置了多个编译时参数,这就是为什么在没有一些要查看的内容的提示的情况下手动分析内核的问题有点不可行。
如果有办法在 NVidia 或 AMD 硬件(我可以访问)上解决此问题,我对此持开放态度。
EDIT
由于我之前的答案显然是错误的,因此我需要有关该问题的更多信息。
通过说“某些内核报告 CL_KERNEL_WORK_GROUP_SIZE 仅 64”,您暗示内核存在于可用的更大工作组大小的地方。是这样吗?如果不是,那么不幸的是,该设备根本无法支持超过 64 个工作项目。
您能否在内核中查询设备的所有可用信息after在执行内核之前设置所有内核参数。参数(主要取自(Source https://stackoverflow.com/questions/23017005/determine-max-global-work-group-size-based-on-device-memory-in-opencl) ) 要查询的是
- CL_DEVICE_GLOBAL_MEM_SIZE
- CL_DEVICE_LOCAL_MEM_SIZE
- CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE
- CL_DEVICE_MAX_MEM_ALLOC_SIZE
- CL_DEVICE_MAX_WORK_GROUP_SIZE
- CL_DEVICE_MAX_WORK_ITEM_SIZES
- CL_KERNEL_WORK_GROUP_SIZE
- CL_KERNEL_LOCAL_MEM_SIZE
- CL_KERNEL_PRIVATE_MEM_SIZE
可能还有更多,但目前没有想到。
一般信息:
由于本地内存有限,因此工作组大小可能受到限制。如果您有一个使用大量私有内存的内核(“很多”是一个相对术语 - 在较弱的硬件上,即使看似很少的变量也可能达到此限制),则可以达到此限制。 “然而,这个限制只是在理想条件下。如果您的内核每个工作组使用大量 WI,则某些私有 WI 数据可能会溢出到本地内存。[...]”(Source https://stackoverflow.com/questions/23017005/determine-max-global-work-group-size-based-on-device-memory-in-opencl).
因此,一些私有内存可能会在您没有意识到的情况下交换到本地内存,因此使用的本地内存的累积大小和交换的私有内存所需的大小大于可用的本地内存大小。
CL_DEVICE_LOCAL_MEM_SIZE
返回本地内存的可用大小,CL_KERNEL_LOCAL_MEM_SIZE
告诉您已经使用了多少本地内存。显然,通过查看 clSetKernelArg 也考虑了动态本地内存,但是我不确定如果您查询这应该如何工作CL_KERNEL_LOCAL_MEM_SIZE before
设置内核参数(这是您想要确定本地内存大小的操作......)
无论如何,OpenCL 确切地知道您使用了多少本地内存,因此它可以计算它可以支持多少个工作项(每个工作项都有可能需要交换到本地内存的私有内存)。您在查询时可能会得到这种减少的本地工作大小CL_KERNEL_WORK_GROUP_SIZE
.
查看您发布的内核后,我不认为本地内存是这里的问题(这是您已经怀疑的),特别是因为您只使用了 32 KiB 本地内存中的 2 个。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)