【发布时间】:2012-06-12 02:05:51
【问题描述】:
我正在使用 CUDA 对可能很大的 3D 数据集进行计算。我觉得最好先看个短代码sn-p:
void launch_kernel(/*arguments . . . */){
int bx = xend-xstart, by = yend-ystart, bz = zend-zstart;
dim3 blocks(/*dimensions*/);
dim3 threads(/*dimensions*/);
kernel<<blocks, threads>>();
}
我有一组 3D 单元,我需要启动一个内核来计算每个单元。问题是输入大小可能超出 GPU 的能力,特别是线程。所以代码如下:
void launch_kernel(/*arguments . . . */){
int bx = xend-xstart, by = yend-ystart, bz = zend-zstart;
dim3 blocks(bx,by,1);
dim3 threads(bz);
kernel<<blocks, threads>>();
}
... 效果不佳。因为如果尺寸是 1000x1000x1000 怎么办? - 我无法在每个块中启动 1000 个线程。或者更好的是,如果尺寸是 5x5x1000 怎么办? - 现在我几乎不启动任何块,但内核需要启动 5x5x512 b/c 的硬件,每个线程将执行 2 次计算。我也不能只是混搭我的所有维度,将一些 z 放在块中,一些放在线程 b/c 中,我需要能够识别内核中的维度。目前:
__global__ void kernel(/*arguments*/){
int x = xstart + blockIdx.x;
int y = ystart + blockIdx.y;
int z = zstart + threadIdx.x;
if(x < xend && y < yend && z < zend){
//calculate
}
}
我需要一种可靠、有效的方法来计算这些变量:
块 x 维度,块 y 维度,线程 x(以及 y? 和 z?),x,y,z 一旦我通过 blockIdx 和 threadIdx 在内核中,如果输入超过硬件,则我在内核计算中的 for 循环中为每个维度采取的“步骤”量。
如果您有任何问题,请提出。这是一个难题,一直困扰着我(尤其是因为我启动的块/线程的数量是性能的主要组成部分)。该代码需要在其针对不同数据集的决策中自动化,我不确定如何有效地做到这一点。提前谢谢你。
【问题讨论】:
-
您使用的是什么 GPU?如果是 Fermi 或 Kepler 卡(计算能力为 2.x 或 3.x),则硬件中支持 3D 网格,这大大简化了事情。
-
没有 3D 网格。它需要能够在相当新的 NVIDIA 显卡上运行(我会说是在过去 4 年内发布的)。
标签: c multidimensional-array cuda gpu