作为更大代码的一部分,我有一个CUDA RK4求解器,它可以并行地集成大量的ODE(可以是1000+)。该操作的一个步骤是计算'xdot',其对于每个等式(或数据元素)是不同的。截至目前,我有一个switch-case分支设置来计算内核中每个数据元素的值。所有不同的线程使用相同的3-6个数据元素来计算它们的输出,但是以不同的方式。例如,对于线程1,它可能是
xdot = data [0] * data [0] + data [1];
而对于线程2,它可能是,
xdot = -2 * data [0] + data [2];
等等。 因此,如果我有一百个数据元素,则每个数据元素的执行路径都不同。
在这种情况下,有没有办法避免/减少线程差异? 每个块只运行一个线程会有什么帮助吗?
答案 0 :(得分:3)
每个块运行一个线程只会使您启动的单个warp中的31/32个线程无效并浪费大量周期和隐藏延迟的机会。无论你的代码产生多少分支差异,我都不会推荐它。
您的应用程序听起来与基本的CUDA编程范例非常相似,并且您可以做的事情不会太多,以避免分支差异惩罚。一种可以略微改进的方法是对每个方程的表达式进行一些事先分析,并将那些具有共同算术项的方法组合在一起。最近的硬件可以同时运行多个内核,因此将共享类似术语的计算分组到不同的内核并同时启动它们而不是单个大内核可能是有利可图的。 CUDA支持C ++模板,这可以是从相对较窄的基础生成大量内核代码并使许多逻辑静态可评估的好方法,这可以帮助编译器。但不要指望奇迹 - 你的问题可能更适合与GPU不同的架构(例如英特尔的Xeon Phi)。