0

我正在处理网格中的项目,根据项目的类型,需要执行不同类型的计算/功能。但是我读过分支在做同样事情的工作项之间是一件非常糟糕的事情。为了避免这种情况,我可以将网格拆分为每种类型的网格(在这种特殊情况下我只需要两个)......

在这种情况下会更好吗?将分支留在那里,或者为每种类型制作两个网格?我知道这取决于分支内部发生的情况(计算界限)与网格的大小(内存/延迟界限)。

这些决定是否有一些基本规则要遵循,或者是否有共识总体上哪个更好?

编辑:(空间)网格并不像通常的空间网格那样稀疏,而是结构的密集数组(没有空元素)(每个结构约 200 个字节),最多可容纳约 500.000 个元素。

我从另一个源填充这个数组,使用那个源我把三角形或线段放在那里。

然后使用这个网格,我需要进行线段/线段或线段/三角形碰撞检测。所以问题是在这种情况下填充两个单独的数组是否会更有效(为了论证,让我们说 250.000 个元素 x 200 字节)并让工作项仅对线/线或线/三角形进行批量计算..或者有一个大的 500.000x200 字节,并让每个工作项找出给定类型要执行的计算。

4

2 回答 2

1

这取决于你的新网格的结构,也取决于你的旧网格。

让我们采取最坏的情况。普通矩形网格(如图像)如果每个奇数项都是类型 1,每个偶数项都是类型 2。现在基本上一半的线程将在 GPU 中处于空闲状态(当类型 1 被计数时,类型 2 线程“空闲”)。这是因为工作组中的项目通常共享它们的程序计数器。

如果您的新网格是 2 个内核调用和简单的“不是 type2?return”,那么它比第一种情况更糟糕。但是,如果您设法制作 2 个网格,其中每个项目的类型都正确,那么最好将其拆分。

如果您的原始网格是具有精确两半的图像,则可能无关紧要。只有边界内的组才会执行额外的工作。

树枝没那么邪恶。只要想一想,只要你有一个分支,甚至工作组中有一个线程(或者你的硬件中的任何调度单元)都会采取与其他人不同的方向,两个分支中的所有代码都将被带到任何地方。

这也是为什么在某些特殊条件适用时不执行昂贵计算等优化通常在 GPU 上不起作用的原因,因为如果其他线程不满足条件,您仍然会在每个线程中有效地计算它。

于 2013-11-06T15:07:45.410 回答
1

对此没有一般规则,视情况而定。如果您使用大量代码,显然重新排列内存会更好。但是,如果您的分支只有 2 条指令,则不要重塑内存。

我会首先对每种类型(CPU 端或简单内核)有多少项目进行分类,然后为每种类型的项目运行一个特定的内核。但是,这可能不适合您的情况。

如果您可以发布一些代码,也许我们可以为您指明正确的方向。

于 2013-11-06T14:57:51.393 回答