CUDA:堆栈和堆

时间:2016-01-14 16:19:26

标签: c++ c cuda

在标题中,有人可以更多地了解CUDA中的堆和堆栈吗?与CPU内存中的原始堆和堆栈有什么不同吗?

当我在CUDA中增加堆栈大小时遇到​​问题,它似乎有其局限性,因为当我将堆栈大小设置为1024 * 300(Tesla M2090)cudaDeviceSetLimit时,我收到错误:{{ 1}}。

我想问的另一个问题是:当我将堆大小设置为非常大的数量(大约2GB)来为我的RTree(数据结构)分配2000个元素时,我在运行时遇到错误:argument invalid

有什么想法吗?

P / s:我只使用单线程(too many resources requested to launch

启动

2 个答案:

答案 0 :(得分:3)

堆栈和堆是不同的东西。 Stack表示每个线程堆栈,堆表示设备malloc / new用于分配内存的每个上下文运行时堆。使用cudaLimitStackSize标志设置堆栈大小,使用cudaLimitMallocHeapSize标志设置运行时堆,两者都传递给cudaDeviceSetLimit API

听起来您想要增加堆大小,但是正在尝试通过更改堆栈大小来实现。另一方面,如果需要大的堆栈大小,则可能必须减少每个块使用的线程数,以避免内核启动失败。

答案 1 :(得分:3)

关于堆栈和堆

堆栈是按线程分配的,并且有硬件限制(见下文)。 驻留在全局内存中,可以使用malloc()进行分配,并且必须使用free()(CUDA doc)显式释放。

此设备的功能:

void* malloc(size_t size);
void free(void* ptr);

可能很有用,但我建议只在真正需要时使用它们。重新考虑使用主机端函数(如cudaMalloc)分配内存的代码是一种更好的方法。

堆栈大小有一个硬件限制,可以通过最小值来计算(根据answer @njuffa):

  • 每个线程的本地内存量
  • 可用的GPU内存/ SM数量/每个SM的最大驻留线程

当你增加大小,并且你只运行一个线程时,我想你的问题是第二个限制,在你的情况下(TESLA M2090)应该是:6144/16/512 = 750KB

具有固定大小(默认为8MB),必须在使用函数malloc()调用cudaDeviceSetLimit之前指定。请注意,由于某些分配开销,分配的内存至少所请求的大小。 另外值得一提的是内存限制不是每线程,而是具有CUDA上下文的生命周期(直到通过调用free()释放)并且可以被后续线程使用内核启动。

堆叠上的相关帖子:... stack frame for kernels... local memory per cuda thread

堆上的相关帖子:... heap memory ...... heap memory limitations per thread