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を割り当てるだけ686MBで、メモリ不足エラーが発生します。しかし、RAMが4GB以上空いています。

次に、割り当てを試行する場合、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 をさらに 6 GB (合計 8​​ GB) に解放したのに、ホストの割り当てがまだ失敗していることです。4GB を malloc しようとすると、正常に動作します。

4

1 に答える 1

3

で割り当てるとcudaMemHostAlloc()、CUDA はネイティブのオペレーティング システム呼び出しを使用して、ページロックされたホスト メモリを割り当てます。OS はすべての物理メモリをページロックすることはできないため、CUDA からの呼び出しに失敗する前に、CUDA に特定の割合の物理メモリを与えるだけで済みます。これにより、失敗がアプリケーションに伝播されます。この動作は OS 固有です。

1 つの方法としては、別の方法でページロック メモリを割り当てることができます (たとえば、Windows では、 with を呼び出すVirtualAlloc()MEM_LARGE_PAGES、その結果のメモリ割り当てがページ ロックされることが保証されます) cuMemHostRegister()。 GPU 用。メモリが既にページ ロックされている場合、これは既存の OS 構造への参照を追加するだけであり、OS は呼び出しのページ ロック部分に失敗しません。cuMemHostAlloc()どちらもホスト ページを GPU のアドレス空間にマップするため、この戦略は成功を保証するcuMemHostRegister()ものではありません。これには失敗する可能性のあるリソース割り当てが必要です。ただし、固定されたメモリを CUDA に要求するよりもうまく機能する可能性があります。

于 2012-08-16T05:54:42.623 に答える