2

作为更大代码的一部分,我有一个 CUDA RK4 求解器,它并行集成了大量 ODE(可以是 1000+)。此操作的一个步骤是计算“xdot”,每个方程(或数据元素)都不同。到目前为止,我有一个 switch-case 分支设置来计算内核中每个数据元素的值。所有不同的线程都使用相同的 3-6 个数据元素来计算它们的输出,但方式不同。例如,对于线程 1,它可能是

xdot = 数据[0]*数据[0] + 数据[1];

而对于线程 2 可能是,

xdot = -2*数据[0] + 数据[2];

等等。因此,如果我有一百个数据元素,每个数据元素的执行路径都不同。

在这种情况下,有什么方法可以避免/减少线程发散惩罚?每个块只运行一个线程会有帮助吗?

4

1 回答 1

3

每个块运行一个线程只会使您启动的单个 warp 中的 31/32 个线程无效,并浪费大量周期和隐藏延迟的机会。我永远不会推荐它,无论您的代码受到多少分支分歧惩罚。

您的应用程序听起来与基本的 CUDA 编程范式非常正交,并且您确实无法做太多事情来避免分支分歧惩罚。可以稍微改进的一种方法是对每个方程的表达式进行一些事先分析,并将具有共同算术项的那些组合在一起。最近的硬件可以同时运行多个内核,因此将共享类似术语的计算分组到不同的内核并同时启动它们可能是有利可图的,而不是单个大内核。CUDA 支持 C++ 模板,这是从相对狭窄的基础生成大量内核代码并使大量逻辑可静态评估的好方法,这有助于编译器。但是不要

于 2013-07-20T09:52:57.227 回答