所有这些CUDA lark在其功能上都是令人头痛的,但我一直想知道的是1d块/网格尺寸的硬限制(通常分别为512/65535)。
当处理范围更大的问题(数百亿)时,是否存在通过内核有效设置"队列"的自动编程方式,或者是手动切片和切割的情况?
每个人如何处理问题划分?
有两种划分数据的基本方法,以便您可以使用CUDA对其进行处理:
- 将数据分解成连续的块,这样每个线程在一个块上工作。
- 每个线程蚕食一个数据元素。当所有线程都完成时,它们通过numberOfThreads移动自己,并重复。
如果一维网格太小,只需使用二维(或CUDA 4.0的费米三维)网格代替。网格和块布局中的维度实际上只是为了方便——它使执行空间看起来像程序员习惯使用的那种常见数据并行输入空间(矩阵、网格、体素等)。但是它只是底层简单的线性编号方案的一个非常小的抽象,可以在单个内核启动中处理超过10^12个唯一的线程id。
在网格中,排序是主要的列,所以如果你之前有一个一维网格问题,"唯一的,一维线程索引"计算为:
unsigned int tid = threadIdx.x + blockIdx.x * blockDim.x;
的理论上限为512 * 65535 = 33553920个唯一线程。等效二维网格问题只是一维情况的简单推广
size_t tidx = threadIdx.x + blockIdx.x * blockDim.x;
size_t tid = tidx + blockIdx.y * blockDim.x * GridDim.x;
的理论上限为512 * 65535 * 65535 = 2198956147200个唯一线程。费米将允许你在网格中添加第三维度,也是65535的最大尺寸,这在单个执行网格中提供了大约10^17个线程。