在Cuda写大型未知大小的数组?

时间:2012-06-18 16:20:35

标签: cuda

我有一个流程,我将数据发送给Cuda进行处理,并输出符合特定条件的数据。问题是我经常不知道输出数组的大小。我该怎么办?

我发送了数百行数据,并在Cuda上以超过20K的不同方式处理。如果结果符合我的一些规则,那么我想保存结果。问题是我不能在Cuda中创建一个链表(如果可以,请告诉我),我的卡上的内存很小,所以我想使用零拷贝让Cuda直接写入主机内存。这解决了我的内存大小问题,但仍然没有给我一个处理未知的方法。

我的主要想法是弄清楚最大可能的结果和malloc这个大小的数组。问题是它会很大并且大多数都不会被使用(800行数据* 20K可能的结果=数组中的1600万个项目......这是不太可能的。)

有没有更好的方法来处理Cuda中的可变大小数组?我是编程的新手,所以理想情况下它不会太复杂(尽管如果它是我愿意学习的话)。

3 个答案:

答案 0 :(得分:1)

在内核代码中使用malloc进行堆内存分配是一项昂贵的操作(它会强制CUDA驱动程序使用自定义堆大小初始化内核并管理内核中的内存操作)。

通常,CUDA设备内存分配是程序性能的主要瓶颈。通常的做法是在开始时分配所有需要的内存,并尽可能长时间地重用它。

我认为您可以创建足够大的缓冲区并使用它而不是内存分配。在最坏的情况下,您可以将其包装以从此缓冲区实现内存分配。在简单的简单情况下,您可以在数组中保留最后一个空闲单元格,以便下次将数据写入其中。

答案 1 :(得分:0)

是的,CUDA和所有GPGPU的东西瓶颈都是从主机转移到设备并返回。

但是在内核中,始终使用已知大小的所有内容。 内核不能做malloc ......从平台的概念来看,这是非常奇怪的。 即使你在CUDA内核中有'for'循环,想想你的方法最优20次,你必须做复杂的算法。在并行平台上真的有必要吗? 如果你不这样做,你不会相信会出现什么问题)))

使用缓冲方法。您确定了一些缓冲区大小,更依赖于CUDA要求(读取 - >硬件),然后是您的阵列。您在循环中调用内核并从那里上载,处理和检索数据。 一个,你的数据数组将完成,最后一个缓冲区将不满。 您可以将每个缓冲区的大小作为单个值(例如指向int的指针)传递,每个线程将与其线程ID进行比较,以确定是否可以获取某个值或者它将超出范围。 只有最后一个区块会有分歧。

答案 2 :(得分:0)

以下是一个有用的链接:https://devblogs.nvidia.com/parallelforall/using-shared-memory-cuda-cc/

你可以使用共享内存在你的内核函数中做这样的事情:

__global__ void dynamicReverse(int *d, int n)
{
  extern __shared__ int s[];
  .....
}

当你在主机上调用内核函数时,第三个参数是共享内存大小,正是n*sizeof(int):   dynamicReverse<<<1,n,n*sizeof(int)>>>(d_d, n);

此外,如果可能的话,将更大的内核函数拆分为更多的内核函数,代码更少且更容易执行,这是最佳实践。

相关问题