Memory 使用CudaMalloc分配的设备内存是否在空闲设备上不可访问?

Memory 使用CudaMalloc分配的设备内存是否在空闲设备上不可访问?,memory,dynamic,cuda,Memory,Dynamic,Cuda,我无法在主机上释放已在设备上分配的内存,也无法在主机上释放已分配的设备上的内存。我在VS2012和Nsight中使用CUDA 5.5。这是因为主机上的堆没有传输到设备上的堆还是相反,所以主机和设备之间的动态分配是未知的 如果这在文档中,就不容易找到。同样重要的是要注意,直到我在CUDA调试和启用内存检查器的情况下运行程序时才抛出错误。这个问题并没有导致CUDA调试之外的崩溃,但如果我没有追溯检查内存问题,以后可能会导致问题。如果有一种简便的方法可以将堆/堆栈从主机复制到设备,那就太棒了。。。希望

我无法在主机上释放已在设备上分配的内存,也无法在主机上释放已分配的设备上的内存。我在VS2012和Nsight中使用CUDA 5.5。这是因为主机上的堆没有传输到设备上的堆还是相反,所以主机和设备之间的动态分配是未知的

如果这在文档中,就不容易找到。同样重要的是要注意,直到我在CUDA调试和启用内存检查器的情况下运行程序时才抛出错误。这个问题并没有导致CUDA调试之外的崩溃,但如果我没有追溯检查内存问题,以后可能会导致问题。如果有一种简便的方法可以将堆/堆栈从主机复制到设备,那就太棒了。。。希望和梦想

下面是我的问题的一个例子:

__global__ void kernel(char *ptr)
{
  free(ptr);
}

void main(void)
{
  char *ptr;
  cudaMalloc((void **)&ptr, sizeof(char *), cudaMemcpyHostToDevice);
  kernel<<<1, 1>>>(ptr);
}
\uuuuu全局\uuuuu无效内核(char*ptr)
{
免费(ptr);
}
真空总管(真空)
{
char*ptr;
cudamaloc((void**)和ptr,sizeof(char*),cudaMemcpyHostToDevice);
内核(ptr);
}
不,你不能这样做

编程指南中专门介绍了此主题

无法使用运行时释放通过malloc()分配的内存(即,通过从设备内存调用任何空闲内存函数)。 类似地,通过运行时分配的内存(即,通过从设备内存调用任何内存分配函数)不能通过free()释放

它在编程指南的B.18.2节中,在B.18节“B.18.动态全局内存分配和操作”中

其基本原因是,用于使用运行时保留分配的机制(例如,
cudamaloc
cudaFree
)与设备代码分配器是分离的,事实上,它们从逻辑上分离的全局内存区域中保留

您可能需要阅读《编程指南》的整个B.18部分,其中涵盖了有关设备动态内存分配的主题。

不,您不能这样做

编程指南中专门介绍了此主题

无法使用运行时释放通过malloc()分配的内存(即,通过从设备内存调用任何空闲内存函数)。 类似地,通过运行时分配的内存(即,通过从设备内存调用任何内存分配函数)不能通过free()释放

它在编程指南的B.18.2节中,在B.18节“B.18.动态全局内存分配和操作”中

其基本原因是,用于使用运行时保留分配的机制(例如,
cudamaloc
cudaFree
)与设备代码分配器是分离的,事实上,它们从逻辑上分离的全局内存区域中保留


您可能需要阅读《编程指南》的整个B.18部分,其中涵盖了有关设备动态内存分配的主题。

以下是我使用CRT在主机上混合动态内存分配、主机CUDA API和内核内存函数的解决方案。首先,如上所述,它们都必须单独管理,使用的策略不需要在系统和设备之间直接传输动态分配,无需事先通信和协调。如Robert的回答/评论中所述,需要手动数据拷贝,但这些拷贝不能针对内核的设备堆进行验证

我还建议跟踪、审核3种不同内存管理API中分配和释放的字节数。例如,每次调用system:malloc、host:cudaMalloc、device:malloc或相关的空闲时,使用一个变量来保存每个堆中分配或释放的字节数,即来自system、host、device的字节数。这有助于在调试时跟踪泄漏

动态分配、管理和审核的过程非常复杂 系统、主机和设备之间的内存透视图 动态结构副本。这里有一个有效的策略,建议 欢迎:

  • 使用计算机的cudaHostMallocmalloc分配系统内存 在系统堆上包含指针的结构类型

  • 从主机为结构分配设备内存,并复制 设备的结构(即cudamaloccudaMemcpy等)

  • 在内核中,使用malloc创建内存分配 使用设备堆进行管理,并将指针保存在 步骤2中设备上存在的结构

  • 通过交换内核分配给系统的内容来进行通信 结构中每个指针的分配大小

  • 主机使用CUDA API在设备上执行相同的分配(即。 cudamaloc)由设备上的内核执行, 建议在结构中为 这,

  • 此时,从内核中动态分配的内存 可以手动将设备内存动态复制到该位置 由主机在设备内存中分配(即不使用主机:memcpy, 设备:memcpycudaMemcpy

  • 内核清理内存分配;以及

  • 主机使用cudaMemcpy将结构从设备中移出,一个 可以使用上述答案评论中概述的类似策略 如有必要,进行深度复制

  • 注意,cudaHostMalloc和system:malloc(或cudaHostMalloc)都共享相同的系统堆,使系统堆和主机堆相同且可互操作,如上文引用的CUDA指南所述。因此,只有系统堆和设备堆是mentio