2012-01-18 5 views
4

私は5636554752バイトのメモリを持っているはずのTesla C2070を持っています。十分なメモリ容量があることがわかっているときにcudaMallocが私にエラーを表示するのはなぜですか?

しかし、これは私にエラーを与える:

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 

、それはLinuxディストリビューションロックス5.4(マーベリック)で、24インテル®Xeon®プロセッサーのX565を持っています。

アイデア?ありがとう!

+6

あなたはどのプラットフォームにいますか? –

+6

どのようなエラーコードが表示されますか? –

+3

'cudaGetErrorString'を使用してエラーコードを印刷すると、いつでも役立ちます。問題のピンポイントを指定します – jwdmsd

答えて

10

基本的な問題は、あなたの質問のタイトルである - あなたが実際にあなたはあなたが想定している、あなたは十分なメモリを持っているを知りません。ランタイムAPIには、デバイス上の空きメモリ容量を返す関数cudaMemGetInfoが含まれています。デバイス上でコンテキストが確立されると、ドライバはデバイスコードのスペース、各スレッドのローカルメモリ、printfのFIFOバッファ、各スレッドのスタック、およびカーネル内のヒープを確保する必要があります。malloc/newコール(詳細はthis answer詳細)。これらのすべてがかなり多くのメモリを消費する可能性があるため、ECC予約後にコードに使用可能であると想定されている最大空きメモリよりもはるかに少ないメモリを使用できます。 APIには、cudaDeviceGetLimitも含まれています。このAPIを使用して、デバイスランタイムサポートで消費しているメモリ量を照会することができます。コンパニオンコール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ウィンドウプラットフォーム、古い既知のドライバの問題)。

関連する問題