3

我正在尝试在资源较少的嵌入式 GPU 上运行一些为桌面显卡编写的 OpenCL 内核。特别是,桌面版假定始终支持至少 256 个工作组大小,但基于 Mali T628 ARM 的 GPU 仅保证 64+ 个工作组大小。

事实上,一些内核报告CL_KERNEL_WORK_GROUP_SIZE只有 64 个,我不知道为什么。我检查了CL_KERNEL_LOCAL_MEM_SIZE有问题的内核,它是 <2 KiB,而CL_DEVICE_LOCAL_MEM_SIZE是 32 KiB,所以我想我可以排除__local存储。

还有哪些其他因素(例如,寄存器/__private内存?)导致 low CL_KERNEL_WORK_GROUP_SIZE,以及如何检查使用情况?我对编程内省(例如clGetKernelWorkGroupInfo()我已经做过的一些)和任何我可能不知道的开发工具持开放态度。

编辑:

内核是 OpenCV 的 OpenCL v2.4 模块的一部分。特别icvCalcOrientationsurf.cl. 代码相当复杂,并且设置了几个编译时参数,这就是为什么手动分析内核的问题而没有一些提示的原因有点不可行。

如果有办法在 NVidia 或 AMD 硬件(我可以访问)上解决这个问题,我愿意接受。

4

2 回答 2

5

编辑

由于我之前的回答显然是错误的,因此我需要有关该问题的更多信息。

通过说“某些内核报告 CL_KERNEL_WORK_GROUP_SIZE 仅为 64”,您暗示内核存在于更大的工作组大小可用的地方。是这样吗?如果不是,那么不幸的答案是该设备根本无法支持超过 64 个工作项。

您能否在设置所有内核参数之后和执行内核之前查询内核中设备的所有可用信息。查询的参数(主要取自(Source))是

  • 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 可能还有更多,但目前没有想到。

一般信息:

可以限制工作组大小,因为本地内存是有限的。如果你有一个使用大量私有内存的内核(“lots”是一个相对术语——在较弱的硬件上,即使看起来很少有变量也可能达到这个限制)。“然而,这个限制只是在理想条件下。如果您的内核在每个 WG 中使用大量 WI,则可能某些私有 WI 数据会溢出到本地内存中。[...]”(来源)。

因此,其中一些私有内存可能会在您没有意识到的情况下交换到本地内存,因此使用的本地内存的累积大小和交换的私有内存所需的大小大于可用的本地内存大小。

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 个。

于 2014-11-23T06:40:49.890 回答
0

还有哪些其他因素(例如,寄存器/__private 内存?)导致 CL_KERNEL_WORK_GROUP_SIZE 低,以及如何检查使用情况?

在 Mali 上,计算工作负载使用的所有内存都是全局的(即支持我的系统 RAM),因此内存压力不会导致任何问题,除非通过次要影响(例如缓存抖动)。我怀疑寄存器分配约束可能会在这里发挥作用——更大的工作组意味着着色器核心中活动的并发线程更多,这意味着对寄存器文件的压力更大——尽管我不确定。

OpenGL ES 的 Mali 离线编译器会报告工作寄存器的使用情况——例如,它可以报告此类信息:

./malisc -c Mali-T760 -r r1p0 -d Mali-T600_r5p0-00rel0 --fragment -V test.frag 
ARM Mali Offline Compiler v4.5.0
(C) Copyright 2007-2014 ARM Limited.
All rights reserved.


1 work registers used, 0 uniform registers used, spilling not used.

        A   L/S T   Total   Bound
Cycles:     2   0   0   2   A
Shortest Path:  1   0   0   1   A
Longest Path:   1   0   0   1   A

Note: The cycles counts do not include possible stalls due to cache misses.

我不确定 ARM 是否有一个可以报告类似信息的 OpenCL 离线编译器——在 ARM Connected Community 网站上询问可能是值得的。

于 2015-03-03T22:56:48.707 回答