Parallel processing 开放式cl中的本地和全局工作尺寸

Parallel processing 开放式cl中的本地和全局工作尺寸,parallel-processing,opencl,gpgpu,Parallel Processing,Opencl,Gpgpu,我正在努力学习开放式cl,但有一个 困惑的根源我不明白,对吗 现在,它与这些线路有关 size_t global_item_size = LIST_SIZE; // Process the entire lists size_t local_item_size = 64; // Divide work items into groups of 64 ret = clEnqueueNDRangeKernel(command_queue, kernel, 1, NULL, &a

我正在努力学习开放式cl,但有一个 困惑的根源我不明白,对吗 现在,它与这些线路有关

size_t global_item_size = LIST_SIZE; // Process the entire lists 
size_t local_item_size = 64; // Divide work items into groups of 64 
ret = clEnqueueNDRangeKernel(command_queue, kernel, 1, NULL, 
        &global_item_size, &local_item_size, 0, NULL, NULL); 
我知道内核在这里是根据线程的列表大小来调用的(我的意思是我在执行中得到了列表大小的内核,希望是并行的)[对吗?] 但这意味着什么

size_t local_item_size = 64; // Divide work items into groups of 64 
?

这是否意味着每个线程/内核都是在64通道simd类波前执行的?(如果是这样的话,我可以称之为双重并行化,但也许我搞混了)


有人能澄清/帮助理解这一点吗?,[也可能添加一些重要提示,在安排写这些内核时需要注意什么?]

工作组大小为64意味着整个工作负载将分成64个工作组。波前的级别比工作组的大小低,并且由硬件/驱动程序控制——即开发人员不能更改波前的大小

工作组可以在内部共享本地内存,但不能与外部组共享。本地内存通常比设备的全局内存快一个数量级。每当您需要多次读取一个值时,将该值缓存在本地内存中是值得的

我想列举一个冗长的例子,说明本地内存和工作组何时有助于提高性能,但它有点偏离了你问题的范围。如果你愿意的话,我仍然可以把它寄出去


编辑: 我觉得如果没有一个例子,这些信息不是很有用。假设您需要在1920x1080图像上运行模糊过滤器。假设每个像素周围有2个像素半径(5x5框)和32位像素(类型:float)

选项1让每个工作项加载一个正方形像素区域,处理目标输出像素,并将结果写回全局内存。这将生成正确的结果,但效率低下。源图像中的每个像素将被各种工作项读取多达25次,全局写入也将分散。我将列出的其他选项不描述全局写入,只描述读取性能提升。 请注意,在幕后,opencl实现仍然将您的工作划分为工作组,即使您没有在代码中使用它们

选项2a利用本地内存和工作组绕过全局内存瓶颈。与现代设备上的全局内存一样快,本地内存仍然快一个数量级。本地内存通常以或接近设备的时钟速度运行。如果使用大小为64的工作组处理同一图像,则工作项可以协同处理输出图像的8x8区域。工作项可以一次性将12x12像素区域加载到本地内存中,处理像素所需的25次读取从本地内存中读取,从而大大提高了性能。每像素的平均全局读取数为1.497(比25!)。240x135工作组可以用这种方式处理整个1920x1080图像

选项2b使用64的工作组大小,您的工作组可以处理更大的图像区域。上面描述的2a使用工作组来处理8x8输出区域,但它仅使用12*12*sizeof(float)(=576字节)的本地内存。通过增加工作组的输出区域,可以减少两倍或四倍读取的边界像素。opencl规范说,设备需要有32kb的本地内存可用。一点数学知识决定了每个工作组可以安全地处理90x90平方像素区域——地板(sqrt(32768/sizeof(float))=90。每个像素的平均全局读取现在是1.041。只需要22x12个工作组


当您能够实现几乎24:1的全局读取次数减少时,即使是低端GPU也可能突然成为ALU性能限制。

如果您阅读了它,说明就非常清楚了。内核函数由每个工作项执行(全局大小)。然后,可以选择一个本地大小,以在每个本地组的工作项之间提供额外的同步。显然,本地大小必须精确地划分全局大小。不明白,您不能解释更多(另外,我已经阅读了这些教程/文档,我无法在脑海中阐明这一点)什么是额外的同步?在谷歌上只需快速搜索就可以获得大量信息。我知道,但我在opencl上读了5天,感到疲惫和困惑-在这种情况下,一些人与人之间的对话可能会有更多帮助。是的,我想要更多的解释。如果可以的话,请回答这个问题:我们在这里谈论两个数字“gloabal”和“local”;(比如1024和64这是真值吗?)全局是否表示处理的内核实例数(希望是并行处理的)?局部表示浮点/整数“通道数”在这1024个内核中的每一个?我把这里的一些东西弄糊涂了,我开始理解的东西。这将是16组1024个内核,或者64个内核,可以通过本地内存在这组中共享…?它们都执行相同的算法?你会选择使用多少组大小,为什么它取决于?一个工作项基本上是这是for循环的一个迭代。当你在opencl设备上运行内核时,这几乎就是实际情况。这些组允许在不同的内核上运行较小的批,并共享本地内存。我添加了一个本地内存共享大大提高性能的示例。好吧,我想可能不是全部,但有些事情我已经澄清了,tnx很多(如果还有一些疑问,我会再建议一次)tnx很多,我似乎理解它。我不知道的是如何做边缘约束。我需要在所有的百万个工作项中使用pust ifs吗?(内核)?如果你有一些经验,你知道gpu处理会快多少吗(低端或miedium级gpu)超过中档CPU?更像是5倍或更多?(我想到的是一个普通到不太乐观的情况)