2016-05-24 1 views
1

システムで現在使用されているvramを取得するために、私はcudaMemGetInfoを使用しています。cudaMemGetInfoはvramを使用し、間違った値を返します

extern __host__ cudaError_t CUDARTAPI cudaMemGetInfo(size_t *free, size_t *total); 

そして、私は二つの問題が生じています:

  • メイングラフィックデバイスは、割り当てのために空きがほとんどないメモリを持っているときに返さ自由値が唯一の権利であるということです。それ以外の場合は、GPU-Zが約80%が使用されていることが明確に示されていても、約20%のメモリが使用されます。そして私が95%のメモリに達すると、cudaMemGetInfoは突然良い値を返します。合計メモリは常に正しいことに注意してください。

  • 第2の問題は、私が関数を使うとすぐに、ビデオメモリが割り当てられることです。少なくとも40mバイトですが、一部のグラフィックデバイスでは400に達することがあります。

マイコード:

#include <cuda_runtime.h> 

size_t Profiler::GetGraphicDeviceVRamUsage(int _NumGPU) 
{ 
    cudaSetDevice(_NumGPU); 

    size_t l_free = 0; 
    size_t l_Total = 0; 
    cudaError_t error_id = cudaMemGetInfo(&l_free, &l_Total); 

    return (l_Total - l_free); 
} 

私は5つのNVIDIAグラフィックデバイスで試してみました。問題は常に同じです。

+0

は 'cudaSetDevice(0)'の間違いですか?すべてのシステムに1つのGPUしかありませんか? – talonmies

+0

現在のシステムには1つのGPUしかありません。しかし、あなたは正しいです、私は私のコード例を単純化しました。ちょうど質問を更新しました。 – Mat

+0

GPUはグラフィックスの表示も担当していますか? –

答えて

0

最初の点では、これを再現することはできません。私は完全な例にコードを展開する場合:

$ ./meminfo 
0 82055168->83103744 
1 83103744->84152320 
2 84152320->85200896 
3 85200896->86249472 
4 86249472->87298048 
5 87298048->88346624 
6 88346624->89395200 
7 89395200->90443776 
8 90443776->91492352 
9 91492352->92540928 
10 92540928->93589504 
11 93589504->94638080 
12 94638080->95686656 
13 95686656->96735232 
14 96735232->97783808 
15 97783808->98832384 
16 98832384->99880960 
17 99880960->100929536 
18 100929536->101978112 
19 101978112->103026688 

と私は、Windows WDDMマシン上でこれを取得する:

#include <iostream> 
size_t GetGraphicDeviceVRamUsage(int _NumGPU) 
{ 
    cudaSetDevice(_NumGPU); 

    size_t l_free = 0; 
    size_t l_Total = 0; 
    cudaError_t error_id = cudaMemGetInfo(&l_free, &l_Total); 

    return (l_Total - l_free); 
} 

int main() 
{ 

    const size_t sz = 1 << 20; 

    for(int i=0; i<20; i++) { 
     size_t before = GetGraphicDeviceVRamUsage(0); 
     char *p; 
     cudaMalloc((void **)&p, sz); 
     size_t after = GetGraphicDeviceVRamUsage(0); 
     std::cout << i << " " << before << "->" << after << std::endl; 
    } 

    return cudaDeviceReset(); 
} 

私は、Linuxマシン上でこれを取得

>meminfo 
0 64126976->65175552 
1 65175552->66224128 
2 66224128->67272704 
3 67272704->68321280 
4 68321280->69369856 
5 69369856->70418432 
6 70418432->71467008 
7 71467008->72515584 
8 72515584->73564160 
9 73564160->74612736 
10 74612736->75661312 
11 75661312->76709888 
12 76709888->77758464 
13 77758464->78807040 
14 78807040->79855616 
15 79855616->80904192 
16 80904192->81952768 
17 81952768->83001344 
18 83001344->84049920 
19 84049920->85098496 

両方を私は一貫しているようです。

2番目のポイント:コンテキストがまだ存在しない場合、cudaSetDeviceは、渡されたデバイス番号にCUDAコンテキストを確立します。 CUDAコンテキストを確立すると、CUDAコードを実行するために必要なランタイムコンポーネントのメモリが予約されます。したがって、あなたが呼び出す関数を含む最初のCUDA APIであれば、関数を呼び出すとメモリを消費するというのは完全に正常です。

+0

ありがとうございました。少なくとも私は自分のコードに間違いがないことを知っています。私の2番目の質問に対するあなたの答えは非常に役に立ちます。 – Mat

関連する問題