我试图了解维度中所有不同的维度参数是如何组合在一起的。如果我的问题不明确,部分是因为一个形式良好的问题需要我没有的答案。
work_dim , global_work_size 和 local_work_size 如何协同工作以创建您在内核中使用的执行空间?例如,如果我制作work_dim 2,那么我可以
get_global_id(0);
get_global_id(1);
我可以使用 global_work_size 将这两个维度划分为n个工作组,对吗?所以,如果我像这样 global_work_size
size_t global_work_size[] = { 4 };
那么每个维度将有4个工作组,总共8个?但是,作为初学者,我只使用global_id作为我的索引,所以只讨论全局id的问题。你可以告诉我,我对所有这些都非常困惑,所以你能提供的任何帮助都会......帮助。
答案 0 :(得分:36)
既然你曾表示自己对执行空间中涉及的概念感到有点困惑,我会在回答你的问题并举一些例子之前尝试总结它们。
线程/工作项在NDRange中组织,可以将其视为1,2,3个dims的网格。 NDRange主要用于将每个线程映射到它们必须操纵的数据片段。因此,每个线程都应该唯一标识,并且线程应该知道它是哪一个以及它在NDRange中的位置。还有工作项内置函数。所有线程都可以调用这些函数来为它们提供有关它们的信息以及它们所处的NDRange。
如前所述,NDRange最多可以有3个维度。因此,如果您以这种方式设置尺寸:
size_t global_work_size[2] = { 4, 4 };
并不意味着每个维度将有4个工作组,总共8个,但是您的NDRange中有4个4个,即16个线程。这些主题将安排在" square"两侧有4个单位。工作项可以使用uint get_work_dim ()
函数知道NDRange的维度。
线程还可以使用size_t get_global_size (uint D)
查询特定维度的NDRange有多大。因此,他们可以知道"线/方/矩形/立方体" NDRange。
由于该组织,每个线程都可以使用与特定维度相对应的索引进行唯一标识。因此,线程(2,1)指的是位于2D范围的第3列和第2行中的线程。函数size_t get_global_id (uint D)
在内核中用于查询线程的id。
NDRange可以分成称为工作组的较小组。这是你所指的local_work_size,它也(并且逻辑上)最多有3个维度。请注意,对于低于2.0的OpenCL版本,给定维度中的NDRange大小必须是该维度中工作组大小的倍数。为了保留你的例子,因为在维度0中我们有4个线程,维度0中的工作组大小可以是1,2,4但不是3.与全局大小类似,线程可以用{{1查询本地大小}}
有时候,一个线程可以在工作组中唯一标识。因此函数size_t get_local_size (uint D)
。注意"内"在上一句中。具有本地id(1,0)的线程将是唯一一个在其工作组(2D)中具有此id的线程。但是将有尽可能多的具有本地id的线程(1,0) )因为NDRange中会有工作组。
有时候一个线程可能需要知道有多少组。这就是函数size_t get_local_id (uint D)
存在的原因。请注意,您必须再次将您感兴趣的维度作为参数传递。
...您可以在内核中使用函数size_t get_num_groups (uint D)
进行查询。请注意,组ID的格式类似于线程的格式:最多3个元素的元组。
如果你有一个全局工作大小为(4,6)并且本地工作大小为(2,2)的 2D NDRange,那么为了总结一下,这意味着:< / p>
这是一个将所有这些概念结合在一起的虚拟示例(注意性能很糟糕,它只是一个愚蠢的例子)。
假设您有一个包含6行和4列int的2D数组。您希望将这些元素分组为2乘2的元素,并以这样的方式对它们求和,例如,元素(0,0),(0,1),(1,0),(1,1)将在一个小组(希望它足够清楚)。因为你将拥有6个&#34;正方形&#34;你总计有6个结果,所以你需要一个包含6个元素的数组来存储这些结果。
要解决此问题,请使用上面详述的2D NDRange。每个线程将从全局内存中获取一个元素,并将其存储在本地内存中。然后在同步之后,每个工作组只有一个线程,假设每个本地(0,0)线程将向上求和元素(在本地),然后将结果存储在6个元素数组(全局)中的特定位置。 / p>
size_t get_group_id (uint D)
通常是的,因为它是你设计算法的一部分。请注意,工作组的大小不是随机的,而是符合我的需要(这里是2乘2平方)。
另请注意,如果您决定使用尺寸为24且局部尺寸为4合1的1维NDRange,那么它也会搞砸,因为内核设计为使用2维。