使用operator new
在CUDA内核函数中分配大内存我在每次启动时将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 - 例外。
为什么会这样? 堆大小是否低于可用内存的大小?
我使用Visual Studio Ultimate 2013和Nsight 4.1。 该设备是GeForce GTX 650 Ti,具有2.0的计算能力。
提前致谢。
UPD1:设备上共有2GB DDR5内存。操作系统是Windows 8.1 Professional x64。
UPD2:我可以使用cudaMalloc()
从主机代码中分配大于1GB的内容。
答案 0 :(得分:1)
我检查了你的卡的规格,它显示只有1024MB的GDDR5设备内存。
这意味着如果你想在卡上有一堆1020MB的设备内存,你将只剩下4MB供驱动程序使用。我想这不会很好。
如果尝试使用内存较多的GPU,则应该能够设置更高的堆大小。
编辑v1 :如果你有一张RAM含量较高的卡,你可以尝试从主机代码动态分配,缓冲区大于1024 MB?如果你不能这样做,那可能是司机的限制。
答案 1 :(得分:0)
通过安装CUDA 7.0版本解决了问题。