>假设我的输入由七个数据点组成,对这些数据点执行一些计算,并将结果写回大小为 7 的输出数组。将块维度声明为 4 会导致网格大小为 2,这会导致尝试运行具有无效线程 ID 的内核(使用 pt_id=blockIdx.x*blockDim.x+threadID.x)为 7,并且由于无效的内存访问而失败(因为我根据线程 ID 访问我的一些数组)。我可以在我的内核中添加代码,专门将线程 id 与 max_thread_id 参数进行比较,并且如果不thread_id>max_thread_id什么也不做,但我想知道是否有一种更漂亮的方法来处理参差不齐的输入数组。
拥有大小不是块维度倍数的任务是很常见的事情。我最常用的解决方案是这个。假设您的输入数据具有大小N
,并且您希望将启动配置为块大小等于 BLOCK_SIZE
。在这种情况下,您的启动配置可能如下所示:
kernel_function<<<(N + BLOCK_SIZE - 1) / BLOCK_SIZE, BLOCK_SIZE>>>(...);
在内核代码中,每个线程确定它是否应该做一些工作,如下所示:
int id = blockIdx.x*blockDim.x + threadIdx.x;
if (id < N) { /* do the stuff */ }
else { return; }
如果任务的大小(N
)取决于输入,你也必须将此值作为参数传递到内核函数中。此外,将N
和BLOCK_SIZE
的值定义为宏或模板参数是很常见的。
最后,如果您的输入数组尺寸较小,例如在您的示例中,GPU 仍然未得到充分利用,并行性不会给您带来任何影响,甚至会降低算法的性能。