3

如何在 OpenCL 中获取二维的全局 threadId?我知道对于一维,公式是:

 int global_id = get_global_id(1) * get_global_size(0) + get_global_id(0);

但如果我这样分配:

size_t block_size[] = {2,2}
size_t grid_size[] = {35,20}

上面的公式失败了,只给出从 0 到 35*20 的索引。索引应该从 0 到 35*40*2*2。

您能否推荐任何可以让我直观地理解所有这些工作原理的好的文档或著作?谢谢!

4

1 回答 1

7

如果您要启动 2D NDRange,那么 get_global_id(0) 和 get_global_id(1) 将为您提供 Gx 和 Gy 索引。您还可以使用 get_local_id(0/1) 独立获取本地 ID。

没必要自己计算。

您的意思是您正在启动一个 2D 线程块,但想将该线程映射到 1 维缓冲区中的某个位置?

编辑:阅读您的评论后,我认为有必要进行解释。

OpenCL 启动与 get_global_size(0) * get_global_size(1) 一样多的内核(即 35 * 20),因此您将拥有线程

(0 ,0) (0 ,1) ... (0,34)
(1 ,0) (1 ,1) ... (1,34)
.
.
.
(19,0) (19,1) ... (19,34)

本地 worksize 只是一种拆分线程总数并将它们分布在可用计算单元中的方法。很可能在任何时间点都只有 2 * 2 = 4 个线程在运行。

clEnqueueNDRangeKernel文档告诉我们 local_work_size 可以为空,在这种情况下,实现将确定分解总工作量的大小。

本地工作大小绝不会增加线程数。

也许这张图片比我能更好地解释它。

OpenCL 2D NDRange

请注意,内核启动的总数仍然是 get_global_size(0) * get_global_size(1)。

如果您希望一维索引从 0..(35*40*2*2 - 1) 开始,则启动内核,以便 get_global_size(0) * get_global_size(1) 为 35*40*2*2 (可能是 70 x 80?)

希望这可以帮助。

于 2013-05-15T15:44:51.557 回答