CUDA:划分*巨大*问题的方法?

CUDA:划分*巨大*问题的方法?,cuda,parallel-processing,gpu,partitioning,gpgpu,Cuda,Parallel Processing,Gpu,Partitioning,Gpgpu,所有这些CUDA lark的能量都在融化,但我一直想知道的是1d块/网格尺寸的硬限制(通常分别为512/65535) 在处理范围大得多的问题时(以数十亿计),是否有一种通过内核有效设置“队列”的自动化编程方式,或者是手动切片和切割的情况 每个人是如何处理问题划分的?如果一维网格太小,只需使用二维(或在费米和CUDA 4.0上使用三维)网格即可。网格和块布局中的维度实际上只是为了方便——它使执行空间看起来像程序员使用的常见数据并行输入空间(矩阵、网格、体素等)。但它只是一个非常小的抽象,与底层的简

所有这些CUDA lark的能量都在融化,但我一直想知道的是1d块/网格尺寸的硬限制(通常分别为512/65535)

在处理范围大得多的问题时(以数十亿计),是否有一种通过内核有效设置“队列”的自动化编程方式,或者是手动切片和切割的情况


每个人是如何处理问题划分的?

如果一维网格太小,只需使用二维(或在费米和CUDA 4.0上使用三维)网格即可。网格和块布局中的维度实际上只是为了方便——它使执行空间看起来像程序员使用的常见数据并行输入空间(矩阵、网格、体素等)。但它只是一个非常小的抽象,与底层的简单线性编号方案不同,该方案可以在单个内核启动中处理10^12个以上的唯一线程ID

在网格中,排序是以列为主的,因此如果您以前遇到过1D网格问题,“唯一的1D线程索引”计算为:

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个唯一线程。Fermi将允许您向网格添加第三维,最大尺寸为65535,在单个执行网格中最多可提供10^17个线程。这相当多。

有两种基本的数据分区方法,您可以使用CUDA处理数据:

  • 将数据分解为连续的,以便每个线程处理一个块
  • 每个线程在一个数据元素上执行半字节操作。当所有线程都完成时,它们会按线程数移动自己,然后再次重复

  • 我已经用简单的例子解释了这些技术。对于大多数任务,方法2通常更容易编码和使用。

    我们不是已经默认在CUDA中设置了队列吗?我所有的问题中都会出现同样的三个人!(没有抱怨)我看到到处都有提到队列,但没有防白痴的例子。内核启动是异步的,两个连续的内核启动(在同一个流上)意味着第二个将“排队”。事实上,我使用队列作为流的别名。但是没有“神奇的”队列。推(kernel())?我对DIY没有问题,但是重新发明轮子并不那么可靠:没有。您可以将任意多个内核调用排队—启动操作是非阻塞的。对于多个流,流id成为内核启动的一部分,即kernel()。默认情况下,所有内容都进入流0,但如果使用多个流,则可以将复制与内核执行重叠,并在费米上同时运行多个内核;假设其他维度为单一维度,则该维度的最大值。谢谢你(一如既往)给出了清晰的答案,但如果是2^9*2^16*2*16还不够的极端情况?(想想在gpu上生成、丢弃和缩减的中间数据集的流化缩减)那么,您必须设计某种分区方案来划分输入空间,或者按顺序处理,或者将其分散到多个设备上。但实际上,设备内存将在可用线程计数之前耗尽。当前最大的GPU只附带6Gb内存,即只有10^9个线程,假设每个线程在每次内核调用时都需要在全局内存中至少唯一的32位类型上运行。