在内核函数中创建对象时发生 CUDA 内存访问冲突

CUDA memory access violation when creating an object in kernel function

为了使用运算符 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。 如果我删除此 class 的构造函数,则在函数

中的 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。 该设备是具有计算能力 2.0 的 GeForce GTX 650 Ti。

提前致谢。


UPD1: 设备总内存为 2GB DDR5。 OS 是 Windows 8.1 Professional x64。

UPD2: 我可以使用 cudaMalloc().

从主机代码分配大于 1GB 的空间

我检查了您的卡的规格,它显示只有 1024MB 的 GDDR5 设备内存。

这意味着如果你想在卡上拥有 1020MB 的设备内存堆,你将只剩下 4MB 供驱动程序使用。我想这不是很好。

如果您尝试使用具有更高内存量的 GPU,您应该能够设置更大的堆大小。


编辑 v1:如果您的卡具有更高的 RAM,您可以尝试从主机代码动态分配 ,超过 1024 MB 的缓冲区?如果你不能这样做,那可能是驱动程序的限制。

问题已通过安装 CUDA 7.0 版本解决。