2016-05-24 3 views
1

Ich verwende cudaMemGetInfo, um den vram zu erhalten, der momentan vom System verwendet wird.cudaMemGetInfo verwendet vram und gibt den falschen Wert zurück.

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

Und ich habe zwei Probleme:

  • die wichtigsten ist, dass der zurück freie Wert nur richtig, wenn die Grafik Gerät fast keinen Speicher frei für die Zuteilung hat. Ansonsten bleibt es bei etwa 20% Speicherverbrauch, selbst wenn GPU-Z klar angibt, dass etwa 80% verwendet werden. Und wenn ich 95% Speicher erreiche, verwendet cudaMemGetInfo plötzlich einen guten Wert. Beachten Sie, dass der Gesamtspeicher immer korrekt ist.

  • Das zweite Problem ist, dass, sobald ich die Funktion verwenden, Videospeicher zugeordnet ist. Mindestens 40 MByte, aber bei einigen Grafikgeräten kann er 400 erreichen.

Mein Code:

#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); 
} 

Ich habe versucht, mit 5 verschiedenen nvidia Grafikgeräten. Die Probleme sind immer gleich.

Irgendeine Idee?

+0

ist das 'cudaSetDevice (0)' ein Fehler? Hast du nur 1 GPU in jedem System? – talonmies

+0

Ich habe nur eine GPU auf meinem aktuellen System. Aber du hast recht, ich habe mein Codebeispiel zu sehr vereinfacht. Habe gerade die Frage aktualisiert. – Mat

+0

Ist die GPU auch für das Grafikdisplay zuständig? –

Antwort

0

Auf Ihren ersten Punkt kann ich das nicht reproduzieren. Wenn ich den Code in ein komplettes Beispiel erweitern:

#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(); 
} 

ich dieses auf einem Linux-Rechner:

$ ./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 

und ich bekomme diese auf einem Windows WDDM:

>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 

Both scheint mir konsequent zu sein.

An Ihrem zweiten Punkt: cudaSetDevice erstellt einen CUDA-Kontext auf der Gerätenummer, die Sie übergeben, wenn kein Kontext bereits existiert. Durch das Einrichten eines CUDA-Kontexts wird Speicher für die Laufzeitkomponenten reserviert, die für die Ausführung von CUDA-Code erforderlich sind. Es ist also völlig normal, dass der Aufruf der Funktion Speicher verbraucht, wenn es sich um die erste CUDA-API-Funktion handelt, die Sie aufrufen.

+0

Vielen Dank für Ihre Hilfe. Zumindest weiß ich, dass mit meinem Code nichts falsch ist. Und deine Antwort auf meine zweite Frage ist sehr hilfreich. – Mat

Verwandte Themen