cudaMalloc 在哪个内存空间分配内存?

Posted

技术标签:

【中文标题】cudaMalloc 在哪个内存空间分配内存?【英文标题】:Which memory space does cudaMalloc allocate memory in? 【发布时间】:2019-12-27 02:22:26 【问题描述】:

如果我理解正确,CUDA 设备有几个不同的memory spaces。 (例如注册、本地、共享、全局等)。调用cudaMalloc()时,分配的内存驻留在哪个内存空间?

例如:

__global__ mykernel (void *p) 
    /* What memory space does p point to? */
    printf("p: %p\n", p);


int main() 
    void *p;
    assert(cudaMalloc (&p, 1024) == CUDA_SUCCESS);
    mykernel<<<1,1024>>> (p);

documentation 没有提到分配内存的级别。它只是说

在设备上分配size字节的线性内存并返回一个指向分配内存的指针。分配的内存适合任何类型的变量对齐。内存没有清空。

似乎内存必须驻留在全局/常量/纹理空间之一中,但哪个?

假设内存永远不会在本地/寄存器/共享内存空间中是否也安全?

【问题讨论】:

【参考方案1】:

全球

cudaMalloc 在全局内存中分配。 全局内存分配的另一种方法是在内核中使用newdelete

__global__ void myKernel(int N)

     int* a = new int[N]; // not recommended
     delete [] a;


共享

对于动态共享内存,你使用 sth like

extern __shared__ int s[];

然后像启动内核一样

myKernel<<<1,n,n*sizeof(int)>>();

或者只是__shared__ int s[4];(内核内部)用于静态共享内存


注册

对于寄存器,您可以考虑 C++ 中的自动分配(仅从语法的角度来看):

int example = 0;
int moreExample[4]

主要区别在于,如果您的寄存器内存用完,您将发生寄存器溢出,并且变量可能最终在全局内存中而不是寄存器中。

【讨论】:

我想确保我理解了最后一部分。我可以将寄存器内存视为每个线程的“堆栈”吗?寄存器和本地内存有什么关系? @user8675309 我的意思是语法。它们就像自动变量。当它们超出范围时它们会死去...... 本地不是新工作吗?每个线程都有一个不同的指针。 @huseyintugrulbuyukisik "new 和 delete 对设备堆内存进行操作。设备允许以这种方式分配一部分全局(即板载)内存。"***.com/questions/14417318/cuda-new-delete。是的,每个线程都有不同的指针。 另一种全局内存分配方法是静态方法,使用__device__装饰器。 (来自主机代码的cudaMalloc() 将被视为动态分配)除了用于内核使用的newdelete,还可以使用malloc()free() 以及cudaMalloc() 进行等效的内核行为和cudaFree()

以上是关于cudaMalloc 在哪个内存空间分配内存?的主要内容,如果未能解决你的问题,请参考以下文章

CUDA C

Java中成员变量分配在哪个空间?

我应该如何为我不知道大小的许多(1000+)数组分配内存?

nvidia cuda访问gpu共享内存

JVM并发分配内存解决方案

在 cuda 中使用静态分配的内存时的全局设备内存大小限制