我想知道如何在OpenCL中为不同的设备选择最佳的本地和全局工作规模? 这是AMD,NVIDIA,INTEL GPU的普遍规则吗? 我应该分析设备的物理构建(多处理器的数量,多处理器中的流处理器的数量等)吗?
这取决于算法/实现吗?因为我看到一些库(如ViennaCL)评估正确的值只是测试了许多本地/全局工作量的组合,并选择了最佳组合。
答案 0 :(得分:11)
NVIDIA建议您的(本地)工作组大小是32的倍数(等于一个warp,这是它们的原子执行单元,这意味着32个线程/工作项原子地一起调度)。另一方面,AMD推荐64的倍数(等于一个波前)。不确定英特尔,但您可以在他们的文档中找到此类信息。
因此,当您进行一些计算并假设您有2300个工作项(全局大小)时,2300不能被64或32分割。如果您没有指定本地大小,OpenCL将选择一个糟糕的本地大小适合你。如果您没有本地大小是原子执行单元的倍数,那么您将获得空闲线程,从而导致设备利用率下降。因此,添加一些“虚拟”线程可能是有益的,这样你就可以获得32/64的倍数的全局大小,然后使用32/64的本地大小(全局大小必须可以通过本地大小分割) )。对于2300,你可以添加4个虚拟线程/工作项,因为2304可以被32个分割。在实际内核中,你可以编写如下内容:
int globalID = get_global_id(0);
if(globalID >= realNumberOfThreads)
globalID = 0;
这将使四个额外的线程与线程0相同。(通常更快做一些额外的工作,然后有许多空闲线程)。
希望能回答你的问题。 GL HF!
答案 1 :(得分:1)
如果您实际上是使用少量内存进行处理(例如存储内核私有状态),您可以为您的问题选择最直观的全局大小,并让OpenCL为您选择本地大小。
请在此处查看我的回答:https://stackoverflow.com/a/13762847/145757
如果内存管理是算法的核心部分并且会对性能产生很大影响,那么您应该更进一步,首先检查最大本地大小(取决于本地/私有)使用 clGetKernelWorkGroupInfo 来确定你的全局大小。