【发布时间】:2015-04-13 09:19:23
【问题描述】:
为了在 CUDA 内核函数中使用运算符 new 分配大内存,我将 cudaLimitMallocHeapSize 的值设置为每次启动时可用设备内存的大小 ~1.7-1.8G。但是如果我尝试在内核函数中创建一个对象,我会在内存检查器抛出的i = 42; 行中遇到内存访问冲突。
代码如下:
class Test
{
private:
int i;
public:
__device__ Test()
{
i = 42;
}
};
__global__ void test()
{
Test *m = new Test();
if (m == NULL)
{
printf("m == NULL\n");
}
else
{
printf("OK\n");
}
}
int main(int argc, char *argv[])
{
size_t free;
size_t total;
cudaMemGetInfo(&free, &total);
cudaCheckError(cudaDeviceSetLimit(cudaLimitMallocHeapSize, free));
test << <1, 1 >> >();
cudaCheckError(cudaDeviceSynchronize());
cudaCheckError(cudaDeviceReset());
return 0;
}
但是在这个异常对象之后Test *m是一个普通对象,地址在设备内存中,其字段i等于42。
如果我去掉这个类的构造函数,在函数中的cuda源文件device_functions.h中会引发同样的异常
static __forceinline__ void* memset(void *dest, int c, size_t n)
{
__nvvm_memset((unsigned char *)dest, (unsigned char)c, n, /*alignment=*/1);
return dest;
}
如果我将堆大小设置为 1*1024*1024*1024 = 1G - 会发生同样的异常。
750 MB - 也不例外。
900 MB - 也不例外。
1000 MB - 也不例外。
1020 MB - 异常。
为什么会这样? 堆大小是否低于可用内存大小的限制?
我正在使用带有 Nsight 4.1 的 Visual Studio Ultimate 2013。 该设备是 GeForce GTX 650 Ti,计算能力为 2.0。
提前致谢。
UPD1: 设备上总共有 2GB DDR5 内存。操作系统为 Windows 8.1 Professional x64。
UPD2:我可以使用 cudaMalloc() 从主机代码分配大于 1GB 的空间。
【问题讨论】:
标签: c++ memory cuda access-violation heap-memory