为啥当我知道有足够的内存空间时 cudaMalloc 会给我一个错误?

Posted

技术标签:

【中文标题】为啥当我知道有足够的内存空间时 cudaMalloc 会给我一个错误?【英文标题】:Why is cudaMalloc giving me an error when I know there is sufficient memory space?为什么当我知道有足够的内存空间时 cudaMalloc 会给我一个错误? 【发布时间】:2012-02-12 22:12:28 【问题描述】:

我有一个应该有 5636554752 字节内存的 Tesla C2070。

但是,这给了我一个错误:

int *buf_d = NULL;

err = cudaMalloc((void **)&buf_d, 1000000000*sizeof(int));

if( err != cudaSuccess)

     printf("CUDA error: %s\n", cudaGetErrorString(err));
     return EXIT_ERROR;

这怎么可能?这与最大内存间距有关吗?以下是 GPU 的规格:

Device 0: "Tesla C2070" 
CUDA Driver Version:    3.20 
CUDA Runtime Version:   3.20 
CUDA Capability Major/Minor version number: 2.0 
Total amount of global memory:  5636554752 bytes 
Multiprocessors x Cores/MP = Cores: 14 (MP) x 32 (Cores/MP) = 448 (Cores) 
Total amount of constant memory:    65536 bytes Total amount of shared memory per block:    49152 bytes Total number of registers available per block: 32768 Warp size: 32 
Maximum number of threads per block:    1024 
Maximum sizes of each dimension of a block: 1024 x 1024 x 64 
Maximum sizes of each dimension of a grid:  65535 x 65535 x 1
Maximum memory pitch: 2147483647 bytes

至于我运行的机器,它有 24 个 Intel® Xeon® 处理器 X565,带有 Linux 发行版 Rocks 5.4 (Maverick)。

有什么想法吗?谢谢!

【问题讨论】:

你在什么平台上? 你得到什么错误代码? 使用“cudaGetErrorString”打印错误代码总是有帮助的。这将查明问题 您能否指定您得到的错误字符串,并通过减小大小来查看您在什么时候停止收到该错误。 我在更新中添加了更多信息。错误是“内存不足” 【参考方案1】:

基本问题在于你的问题标题 - 你实际上并不知道你有足够的记忆,你是假设你知道。运行时 API 包括 cudaMemGetInfo 函数,该函数将返回设备上有多少可用内存。当在设备上建立上下文时,驱动程序必须为设备代码、每个线程的本地内存、printf 支持的 fifo 缓冲区、每个线程的堆栈以及内核内malloc/new 的堆保留空间电话(有关详细信息,请参阅this answer)。所有这些都会消耗相当多的内存,使您在 ECC 保留后的最大可用内存远少于您假设代码可用的最大可用内存。 API 还包括cudaDeviceGetLimit,您可以使用它来查询设备运行时支持所消耗的内存量。还有一个伴随调用 cudaDeviceSetLimit 可以让您更改运行时支持的每个组件将保留的内存量。

即使您根据自己的喜好调整了运行时内存占用并从驱动程序中获得了实际的可用内存值,仍然需要处理页面大小粒度和碎片问题。很少有可能分配 API 将报告为免费的每个字节。通常,当目标是尝试分配卡上的每个可用字节时,我会这样做:

const size_t Mb = 1<<20; // Assuming a 1Mb page size here

size_t available, total;
cudaMemGetInfo(&available, &total);

int *buf_d = 0; 
size_t nwords = total / sizeof(int);
size_t words_per_Mb = Mb / sizeof(int);

while(cudaMalloc((void**)&buf_d,  nwords * sizeof(int)) == cudaErrorMemoryAllocation)

    nwords -= words_per_Mb;
    if( nwords  < words_per_Mb)
    
        // signal no free memory
        break;
    


// leaves int buf_d[nwords] on the device or signals no free memory

(注意从未靠近过编译器,仅在 CUDA 3 或更高版本上安全)。隐含地假设大分配问题的明显来源都不适用于此处(32 位主机操作系统、未启用 TCC 模式的 WDDM Windows 平台、较早的已知驱动程序问题)。

【讨论】:

谢谢。我使用cudaMemGetInfo 来获取我的gpu 内存信息,2147483648 中只有13614248 是空闲的,即0.6%,为什么空闲内存这么小?我绝对不会在 GPU 上使用其他任何东西......

以上是关于为啥当我知道有足够的内存空间时 cudaMalloc 会给我一个错误?的主要内容,如果未能解决你的问题,请参考以下文章

vivo手机安装失败,可是内存足够,为啥

为啥操作系统说内存足够时无法为jvm分配内存

当我仍然有足够的内存时,cuda push::sort 遇到了内存问题

为啥linux有足够的内存但是使用了swap

sparklyr中的堆空间不足,但有足够的内存

什么是虚拟内存?为什么说我的虚拟内存中没有足够的自由空间?