cuMemHostAlloc内存不足错误

时间:2012-08-15 12:32:03

标签: memory cuda

我有一个内存分配问题我无法理解。我试图分配相当大的GPU内存(我猜它可能是一个内存碎片问题?)

我非常简化的代码是:

#include <stdio.h>
#include <cuda.h>

int main()
{
    CUcontext ctx;
    CUdevice dev = 0;
    void *toSpace;
    CUdeviceptr ptr = (CUdeviceptr)NULL;
    int status;
    int size = 1280*1024*1024;

    status = cuInit(0);
    printf("status: %i\n",status); 

    status = cuCtxCreate(&ctx, 0, dev);
    printf("status: %i\n",status); 

    status = cuMemHostAlloc(&toSpace, size, 0); 
    printf("status: %i\n",status); 

    status = cuMemAlloc(&ptr, size);
    printf("status: %i\n",status); 

    status = cuCtxDestroy(ctx);
    printf("status: %i\n",status); 

    printf("\nPress any key to exit...");
    char c;
    scanf("%c", &c);

    return 0;
}

Editted:

cuMemHostAlloc只允许我分配686MB,我的内存错误就会消失。但我有超过4GB的RAM。

如果我尝试使用cuMemAlloc进行分配,那么我也想分配GPU内存。我最多可以1279MB。但根据设备信息,我2048MB 1981MB是免费的。

如果这是碎片问题,无论如何都要找到我可以分配的最大内存块?

设备信息

Version:                       2.1
Name:                          GeForce GT 525M
Total global memory:           1981/2047 (Free/Total) MBytes
Total registers per block:     32768    
Warp size:                     32
Maximum memory pitch:          2147483647
Maximum threads per block:     1024
Total shared memory per block  49152 Bytes
Clock rate:                    1 MHz
Memory Clock rate:             900000
Total constant memory:         65536
Integrated:                    0
Max threads per multiprocessor:1536
Number of multiprocessors:     2
Maximum dimension x of block:  1024
Maximum dimension y of block:  1024
Maximum dimension z of block:  64
Maximum dimension x of grid:   65535
Maximum dimension y of grid:   65535
Maximum dimension z of grid:   65535

更新:

所以经过多次扫描后,GPU内存分配很好,我相信主机分配出错了。

问题是我现在将更多内存释放到6GB(总共8GB),主机分配仍然失败。如果我尝试使用malloc 4GB,虽然它工作正常。

1 个答案:

答案 0 :(得分:3)

使用cudaMemHostAlloc()分配时,CUDA使用本机操作系统调用来分配页锁定主机内存。操作系统无法对所有物理内存进行页面锁定,因此在CUDA未能通过CUDA调用之前,它只愿意为CUDA提供一定比例的物理内存。此行为是特定于操作系统的。

您可以通过其他方式分配页面锁定内存(例如,在Windows上,使用VirtualAlloc()调用MEM_LARGE_PAGES,并保证生成的内存分配被页面锁定)调用cuMemHostRegister(),页面锁定并映射GPU的现有虚拟内存范围。如果内存已经被页面锁定,那么这将只添加对现有OS结构的引用,并且操作系统不会使调用的页锁定部分失败。此策略不能保证成功,因为cuMemHostAlloc()cuMemHostRegister()都将主机页面映射到GPU的地址空间,这确实需要一些可能失败的资源分配;但它可能比仅仅向CUDA询问固定内存更好。