确定OpenCL工作组大小的限制因素?

确定OpenCL工作组大小的限制因素?,opencl,mali,Opencl,Mali,我正在尝试用更少的资源在嵌入式GPU上运行一些为桌面图形卡编写的OpenCL内核。特别是,桌面版本假定始终支持至少256个工作组大小,但基于ARM的GPU仅保证64个以上的工作组大小 事实上,一些内核报告称CL\u KERNEL\u WORK\u GROUP\u SIZE只有64个,我不明白为什么。我检查了有问题的内核的CL\u KERNEL\u LOCAL\u MEM\u SIZE,它是编辑的 由于我之前的回答显然是错误的,我需要更多关于这个问题的信息 通过说“一些内核报告CL_内核_工作_组

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

事实上,一些内核报告称
CL\u KERNEL\u WORK\u GROUP\u SIZE
只有64个,我不明白为什么。我检查了有问题的内核的
CL\u KERNEL\u LOCAL\u MEM\u SIZE
,它是编辑的 由于我之前的回答显然是错误的,我需要更多关于这个问题的信息

通过说“一些内核报告CL_内核_工作_组_大小仅为64”,你是在暗示内核存在于工作组大小较大的地方。是这样吗?如果不是,那么不幸的是,这个设备不能支持超过64个工作项

在设置所有内核图形之后和执行内核之前,请在内核中查询设备中的所有可用信息。要查询的参数(主要取自())如下

  • CL\ U设备\全局\成员\大小
  • CL\ U设备\本地\内存\大小
  • CL\u设备\u最大\u常数\u缓冲区\u大小
  • CL_设备_最大_内存_所有尺寸
  • CL\ U设备\最大\工作\组\大小
  • CL\ U设备\最大\工作\项目\尺寸
  • CL\内核\工作\组\大小
  • CL_内核_本地_内存_大小
  • CL_内核_私有_成员_大小 可能还有更多,但目前还没有人想到
一般资料:

./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.
由于本地内存有限,因此可以限制工作组的大小。如果你有一个使用大量私有内存的内核,那么这个限制是可以达到的(“lots”是一个相对的术语——在较弱的硬件上,即使变量看起来很少,也可能达到这个限制)。“然而,这个限制只是在理想情况下。如果您的内核在每个工作组中使用了大量的WI,可能一些私有WI数据正在溢出到本地内存。[…]”()

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

CL\u DEVICE\u LOCAL\u MEM\u SIZE
返回本地内存的可用大小,
CL\u KERNEL\u LOCAL\u MEM\u SIZE
告诉您使用了多少本地内存。另外,通过查看clSetKernelArg,这也考虑了动态本地内存,但是如果在设置内核参数之前查询
CL_KERNEL_local_MEM_SIZE(这是确定本地内存大小所需的操作),我不确定这应该如何工作

无论如何,OpenCL确切地知道您使用了多少本地内存,因此它可以计算出它可以支持多少个工作项(每个工作项都有可能需要交换到本地内存的私有内存)。当查询
CL\u内核\u工作\u组\u大小时,您可能会得到这种减少的本地工作大小

在查看了您发布的内核之后,我认为本地内存不是问题所在(这是您已经怀疑的),特别是因为您只使用了32kib本地内存中的2个

还有哪些其他因素(例如寄存器/专用内存?)导致低内存 CL\内核\工作\组\大小,如何检查使用情况

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

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

./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连接的社区网站上询问可能是值得的。

您的内核使用动态本地内存还是“静态”(自动)本地内存,例如
本地浮点[64]
?还可以看看@Baizz静态本地内存。在我发布之前,我看到了这个问题,但我不知道它们中的任何一个如何帮助找出工作组大小受到限制的原因。等等,你是说
CL\u DEVICE\u LOCAL\u MEM\u size
剩余的本地内存量是多少?我认为这是本地内存使用量的问题。如果它的使用量和我想的一样,那么在阅读文档之后,结果证明我错了
CL\u DEVICE\u LOCAL\u MEM\u SIZE
返回本地内存的可用大小,
CL\u KERNEL\u LOCAL\u MEM\u SIZE
告诉您使用了多少本地内存。另外,通过查看
clSetKernelArg
,这也考虑了动态本地内存,但是如果在设置内核参数之前查询
CL\u KERNEL\u local\u MEM\u SIZE
(这是确定本地内存大小所需的操作),我不确定这应该如何工作。无论如何,我可能不得不重新思考你的问题和我的答案。
你是在暗示内核存在于工作组规模更大的地方。是这样吗?
是的,在许多内核上,支持的工作组大小是128或256,即使在内核上也是如此。我将在本周末或下周初了解您提到的所有参数,并向您汇报。顺便说一句,谢谢你的帮助!你那边有什么消息吗?