0

我有一个过程,我将数据发送到 Cuda 进行处理,它输出符合特定标准的数据。问题是我经常不知道输出数组的大小。我能做些什么?

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

我最初的想法是找出最大可能的结果并 malloc 一个该大小的数组。问题是它会很大,而且大多数都不会被使用(800 行数据 * 20K 可能的结果 = 数组中的 1600 万个项目......这不太可能)。

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

4

3 回答 3

1

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

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

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

于 2012-06-18T18:53:43.443 回答
0

是的,CUDA 和所有 GPGPU 的瓶颈都是从主机传输到设备并返回。

但是在内核中,总是使用所有已知大小的东西。内核一定不能做malloc……从平台的概念上来说是非常非常奇怪的。即使您在 CUDA 内核中有 'for' - 循环,想想 20 次左右是您的最佳方法,您必须执行非常复杂的算法。在并行平台上真的有必要吗?如果您不这样做,您将不会相信会出现什么问题)))

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

于 2016-01-15T19:25:39.347 回答
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);

此外,如果可能的话,最好的做法是将一个巨大的内核函数拆分为更多的内核函数,代码更少并且更容易执行。

于 2016-07-08T21:37:59.567 回答