1

我有一个我不太明白的内存分配问题。我正在尝试分配相当大的 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;
}

编辑:

cuMemHostAlloc只让我 allocate 686MB,我得到内存错误。但我有超过 4GB 的可用 RAM。

然后,如果我尝试分配 GPU 内存,cuMemAlloc我也想分配最多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 内存分配之后,我相信这是主机分配出错了。

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

4

1 回答 1

3

当您使用 分配时cudaMemHostAlloc(),CUDA 使用本机操作系统调用来分配页面锁定的主机内存。操作系统无法对所有物理内存进行页面锁定,因此它只愿意在 CUDA 调用失败之前给 CUDA 一定比例的物理内存,然后将失败传播到您的应用程序。此行为是特定于操作系统的。

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

于 2012-08-16T05:54:42.623 回答