【问题标题】:CUDA memory access violation when creating an object in kernel function在内核函数中创建对象时 CUDA 内存访问冲突
【发布时间】: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


    【解决方案1】:

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

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

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


    Edit v1:如果你有一张内存更大的卡,你可以尝试从主机代码中动态分配,一个大于1024的缓冲区兆?如果你不能这样做,那可能是驱动程序的限制。

    【讨论】:

    • 是的,我认为你是对的。似乎 cudaMemGetInfo(&free, &total);总是返回 > 1024 MB,因为操作系统会扩展设备内存。并且堆大小应该小于空闲设备硬件内存。在官方 CUDA 库文档中并不清楚:“分别返回 *free 和 *total,以字节为单位可供设备分配的空闲和总内存量。”
    • 存在2GB的GTX 650 Ti版本,例如this one。但是,如果 OP 澄清他们拥有哪张卡,这可能会很有用。我认为cudaMemGetInfo 报告的内存永远不会超过卡上的物理内存。
    • Robert Crovella,CPU-Z 显示 2048 MB 内存,可能是操作系统或驱动程序限制了应用程序的可用内存?
    • 你能从主机代码分配一个大于1020MB的设备缓冲区吗?我记得低端卡有这个驱动限制,你不能分配一个大于设备 RAM 1/2 的缓冲区。
    • 是的,我尝试通过 cudaMalloc(&amp;p, 1.5*1024*1024*1024) 分配 1.5G - 没有错误。 p 有一个有效的设备内存地址。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2012-06-15
      • 2013-08-10
      • 2021-11-07
      • 2012-06-26
      • 2015-07-31
      • 1970-01-01
      • 1970-01-01
      • 2015-01-28
      • 2017-09-20
      相关资源
      最近更新 更多