Warum nicht CudaFree scheinen, um Speicher frei?
Ich versuche zu reservieren Gerätespeicher zu kopieren, führen Sie die Berechnungen auf die GPU kopieren Sie die Ergebnisse zurück und dann frei bis das Gerät die Erinnerung, die ich zugeordnet. Ich wollte sichergehen, dass ich nicht gehen über die Grenze und ich wollte sehen, ob ich genug Speicher in den gemeinsamen Speicher-dump, ein paar arrays.
Wenn ich reservieren Gerät Speicher, es werden keine Fehler zurückgegeben. Wenn ich cudaMemGetInfo
zu überprüfen, die Menge an Speicher, sieht es aus wie eine cudaMalloc
noch nicht zugewiesenen Speicher.
Auch wenn ich versuche den Speicher frei, es sieht aus wie nur ein Zeiger freigegeben wird.
Ich bin mit der matlab Mexfunction
- Schnittstelle zur Einstellung der GPU-Speicher und starten den kernel. An diesem Punkt bin ich nicht auch ein Aufruf an die kernel-und nur er wieder eine Einheit matrix für die Ergebnisse.
cudaError_t cudaErr;
size_t freeMem = 0;
size_t totalMem = 0;
size_t allocMem = 0;
cudaMemGetInfo(&freeMem, &totalMem);
mexPrintf("Memory avaliable: Free: %lu, Total: %lu\n",freeMem, totalMem);
/* Pointers for the device memory */
double *devicePulseDelay, *deviceTarDistance, *deviceScattDistance, *deviceScatterers;
double *deviceReceivedReal, *deviceReceivedImag;
/* Allocate memory on the device for the arrays. */
mexPrintf("Allocating memory.\n");
cudaErr = cudaMalloc( (void **) &devicePulseDelay, sizeof(double)*512);
if (cudaErr != cudaSuccess)
{
mexPrintf("could not allocate memory to devicePulseDelay\n");
mexPrintf("Error: %s\n",cudaGetErrorString(cudaErr));
}
cudaMemGetInfo(&allocMem, &totalMem);
mexPrintf("devicePulseDelay: Memory avaliable: Free: %lu, Total: %lu, Consumed: %lu\n",allocMem, totalMem,(freeMem - allocMem));
cudaErr = cudaMalloc( (void **) &deviceTarDistance, sizeof(double)*512);
if (cudaErr != cudaSuccess)
{
mexPrintf("could not allocate memory to deviceTarDistance\n");
mexPrintf("Error: %s\n",cudaGetErrorString(cudaErr));
}
cudaMemGetInfo(&allocMem, &totalMem);
mexPrintf("deviceTarDistance: Memory avaliable: Free: %lu, Total: %lu, Consumed: %lu\n",allocMem, totalMem,(freeMem - allocMem));
cudaErr = cudaMalloc( (void **) &deviceScattDistance, sizeof(double)*999*512);
if (cudaErr != cudaSuccess)
{
mexPrintf("could not allocate memory to deviceScattDistance\n");
mexPrintf("Error: %s\n",cudaGetErrorString(cudaErr));
}
cudaMemGetInfo(&allocMem, &totalMem);
mexPrintf("deviceScattDistance: Memory avaliable: Free: %lu, Total: %lu, Consumed: %lu\n",allocMem, totalMem,(freeMem - allocMem));
cudaErr = cudaMalloc( (void **) &deviceScatterers, sizeof(double)*999);
if (cudaErr != cudaSuccess)
{
mexPrintf("could not allocate memory to deviceScatterers\n");
mexPrintf("Error: %s\n",cudaGetErrorString(cudaErr));
}
cudaMemGetInfo(&allocMem, &totalMem);
mexPrintf("deviceScatterers: Memory avaliable: Free: %lu, Total: %lu, Consumed: %lu\n",allocMem, totalMem,(freeMem - allocMem));
cudaErr = cudaMalloc( (void **) &deviceReceivedReal, sizeof(double)*999*512);
if (cudaErr != cudaSuccess)
{
mexPrintf("could not allocate memory to deviceReceivedReal\n");
mexPrintf("Error: %s\n",cudaGetErrorString(cudaErr));
}
cudaMemGetInfo(&allocMem, &totalMem);
mexPrintf("deviceReceivedReal: Memory avaliable: Free: %lu, Total: %lu, Consumed: %lu\n",allocMem, totalMem,(freeMem - allocMem));
cudaErr = cudaMalloc( (void **) &deviceReceivedImag, sizeof(double)*999*512);
if (cudaErr != cudaSuccess)
{
mexPrintf("could not allocate memory to deviceReceivedImag\n");
mexPrintf("Error: %s\n",cudaGetErrorString(cudaErr));
}
cudaMemGetInfo(&allocMem, &totalMem);
mexPrintf("deviceReceivedImag: Memory avaliable: Free: %lu, Total: %lu, Consumed: %lu\n", allocMem, totalMem,(freeMem - allocMem));
/* copy the input arrays across to the device */
mexPrintf("\nCopying memory.\n");
cudaErr = cudaMemcpy(devicePulseDelay, pulseDelay, sizeof(double)*512,cudaMemcpyHostToDevice);
if (cudaErr != cudaSuccess)
{
mexPrintf("could not copy to devicePulseDelay\n");
mexPrintf("Error: %s\n",cudaGetErrorString(cudaErr));
}
cudaMemGetInfo(&allocMem, &totalMem);
mexPrintf("devicePulseDelay: Memory avaliable: Free: %lu, Total: %lu, Consumed: %lu\n",allocMem, totalMem,(freeMem - allocMem));
cudaErr = cudaMemcpy(deviceTarDistance, tarDistance, sizeof(double)*512,cudaMemcpyHostToDevice);
if (cudaErr != cudaSuccess)
{
mexPrintf("could not copy to deviceTarDistance\n");
mexPrintf("Error: %s\n",cudaGetErrorString(cudaErr));
}
cudaMemGetInfo(&allocMem, &totalMem);
mexPrintf("deviceTarDistance: Memory avaliable: Free: %lu, Total: %lu, Consumed: %lu\n",allocMem, totalMem,(freeMem - allocMem));
cudaErr = cudaMemcpy(deviceScattDistance, scattDistance, sizeof(double)*999*512,cudaMemcpyHostToDevice);
if (cudaErr != cudaSuccess)
{
mexPrintf("could not copy to deviceScattDistance\n");
mexPrintf("Error: %s\n",cudaGetErrorString(cudaErr));
}
cudaMemGetInfo(&allocMem, &totalMem);
mexPrintf("deviceScattDistance: Memory avaliable: Free: %lu, Total: %lu, Consumed: %lu\n",allocMem, totalMem,(freeMem - allocMem));
cudaErr = cudaMemcpy(deviceScatterers, scatterers, sizeof(double)*999,cudaMemcpyHostToDevice);
if (cudaErr != cudaSuccess)
{
mexPrintf("could not copy to deviceScatterers\n");
mexPrintf("Error: %s\n",cudaGetErrorString(cudaErr));
}
cudaMemGetInfo(&allocMem, &totalMem);
mexPrintf("deviceScatterers: Memory avaliable: Free: %lu, Total: %lu, Consumed: %lu\n",allocMem, totalMem,(freeMem - allocMem));
/* call the kernel */
//launchKernel<<<1,512>>>(........);
/* retireve the output */
cudaErr = cudaMemcpy(receivedReal, deviceReceivedReal, sizeof(double)*512*512,cudaMemcpyDeviceToHost);
if (cudaErr != cudaSuccess)
{
mexPrintf("could not copy to receivedReal\n");
mexPrintf("Error: %s\n",cudaGetErrorString(cudaErr));
}
cudaMemGetInfo(&allocMem, &totalMem);
mexPrintf("receivedReal: Memory avaliable: Free: %lu, Total: %lu, Consumed: %lu\n",allocMem, totalMem,(freeMem - allocMem));
cudaErr = cudaMemcpy(receivedImag, deviceReceivedImag, sizeof(double)*512*512,cudaMemcpyDeviceToHost);
if (cudaErr != cudaSuccess)
{
mexPrintf("could not copy to receivedImag\n");
mexPrintf("Error: %s\n",cudaGetErrorString(cudaErr));
}
cudaMemGetInfo(&allocMem, &totalMem);
mexPrintf("receivedImag: Memory avaliable: Free: %lu, Total: %lu, Consumed: %lu\n",allocMem, totalMem,(freeMem - allocMem));
/* free the memory. */
mexPrintf("\nFree'ing memory.\n");
cudaMemGetInfo(&freeMem, &totalMem);
mexPrintf("Before freeing: Free %lu, Total: %lu\n", freeMem, totalMem);
cudaErr = cudaFree(devicePulseDelay);
if (cudaErr != cudaSuccess)
{
mexPrintf("could free devicePulseDelay\n");
mexPrintf("Error: %s\n",cudaGetErrorString(cudaErr));
}
cudaMemGetInfo(&allocMem, &totalMem);
mexPrintf("devicePulseDelay: Memory avaliable: Free: %lu, Total: %lu, Free'd: %lu\n",allocMem, totalMem,(allocMem - freeMem));
cudaErr = cudaFree(deviceTarDistance);
if (cudaErr != cudaSuccess)
{
mexPrintf("could free deviceTarDistance\n");
mexPrintf("Error: %s\n",cudaGetErrorString(cudaErr));
}
cudaMemGetInfo(&allocMem, &totalMem);
mexPrintf("deviceTarDistance: Memory avaliable: Free: %lu, Total: %lu, Free'd: %lu\n",allocMem, totalMem,(allocMem - freeMem));
cudaErr = cudaFree(deviceScattDistance);
if (cudaErr != cudaSuccess)
{
mexPrintf("could free deviceScattDistance\n");
mexPrintf("Error: %s\n",cudaGetErrorString(cudaErr));
}
cudaMemGetInfo(&allocMem, &totalMem);
mexPrintf("deviceScattDistance: Memory avaliable: Free: %lu, Total: %lu, Free'd: %lu\n",allocMem, totalMem,(allocMem - freeMem));
cudaErr = cudaFree(deviceScatterers);
if (cudaErr != cudaSuccess)
{
mexPrintf("could free deviceScatterers\n");
mexPrintf("Error: %s\n",cudaGetErrorString(cudaErr));
}
cudaMemGetInfo(&allocMem, &totalMem);
mexPrintf("deviceScatterers: Memory avaliable: Free: %lu, Total: %lu, Free'd: %lu\n",allocMem, totalMem,(allocMem - freeMem));
cudaErr = cudaFree(deviceReceivedReal);
if (cudaErr != cudaSuccess)
{
mexPrintf("could free deviceReceivedReal\n");
mexPrintf("Error: %s\n",cudaGetErrorString(cudaErr));
}
cudaMemGetInfo(&allocMem, &totalMem);
mexPrintf("deviceReceivedReal: Memory avaliable: Free: %lu, Total: %lu, Free'd: %lu\n",allocMem, totalMem,(allocMem - freeMem));
cudaErr = cudaFree(deviceReceivedImag);
if (cudaErr != cudaSuccess)
{
mexPrintf("could free deviceReceivedImag\n");
mexPrintf("Error: %s\n",cudaGetErrorString(cudaErr));
}
cudaMemGetInfo(&allocMem, &totalMem);
mexPrintf("deviceReceivedImag: Memory avaliable: Free: %lu, Total: %lu, Free'd: %lu\n",allocMem, totalMem,(allocMem - freeMem));
Hier ist die Ausgabe von diesem:
Speicher verfügbar: Kostenlos: 2523959296, Gesamt: 2818572288 Reservieren von Speicher. devicePulseDelay: Speicher verfügbar: Kostenlos: 2522910720, Gesamt: 2818572288, Verbraucht: 1048576 deviceTarDistance: Speicher verfügbar: Kostenlos: 2522910720, Gesamt: 2818572288, Verbraucht: 1048576 deviceScattDistance: Speicher verfügbar: Kostenlos: 2518716416, Gesamt: 2818572288, Verbraucht: 5242880 deviceScatterers: Speicher verfügbar: Kostenlos: 2517667840, Gesamt: 2818572288, Verbraucht: 6291456 deviceReceivedReal: Speicher verfügbar: Kostenlos: 2515570688, Gesamt: 2818572288, Verbraucht: 8388608 deviceReceivedImag: Speicher verfügbar: Kostenlos: 2513473536, Gesamt: 2818572288, Verbraucht: 10485760 Kopieren von Speicher. devicePulseDelay: Speicher verfügbar: Kostenlos: 2513473536, Gesamt: 2818572288, Verbraucht: 10485760 deviceTarDistance: Speicher verfügbar: Kostenlos: 2513473536, Gesamt: 2818572288, Verbraucht: 10485760 deviceScattDistance: Speicher verfügbar: Kostenlos: 2513473536, Gesamt: 2818572288, Verbraucht: 10485760 deviceScatterers: Speicher verfügbar: Kostenlos: 2513473536, Gesamt: 2818572288, Verbraucht: 10485760 receivedReal: Speicher verfügbar: Kostenlos: 2513473536, Gesamt: 2818572288, Verbraucht: 10485760 receivedImag: Speicher verfügbar: Kostenlos: 2513473536, Gesamt: 2818572288, Verbraucht: 10485760 Frei ' Ing-Speicher. Vor der Befreiung: Frei 2513473536, Gesamt: 2818572288 devicePulseDelay: Speicher verfügbar: Kostenlos: 2513473536, Gesamt: 2818572288, Frei hatte: 0 deviceTarDistance: Speicher verfügbar: Kostenlos: 2513473536, Gesamt: 2818572288, Frei hatte: 0 deviceScattDistance: Speicher verfügbar: Kostenlos: 2513473536, Gesamt: 2818572288, Frei hatte: 0 deviceScatterers: Speicher verfügbar: Kostenlos: 2514522112, Gesamt: 2818572288, Frei würde: 1048576 deviceReceivedReal: Speicher verfügbar: Kostenlos: 2514522112, Gesamt: 2818572288, Frei würde: 1048576 deviceReceivedImag: Speicher verfügbar: Kostenlos: 2514522112, Gesamt: 2818572288, Frei würde: 1048576
Ich fühle mich wie es ist etwas offensichtlich, dass ich vermisst. Kann mir jemand helfen, erklären, was Los ist?
EDIT: Plattform ist windows 7 mit einem Tesla C2050 GPu-Karte.
- Welche Plattform verwendest du diesen code auf?
- Versuchen zu null zu den Werten von allocMem und totalMem vor jedem Aufruf cudaMemGetInfo() und überprüfen Sie den Rückgabewert von cudaMemGetInfo().
- zero ' Ing aus der allocMem und totalMem vor jedem Aufruf cudaMemGetInfo() kein Unterschied gemacht. Auch die cudaMemGetInfo Anrufe kamen nicht wieder irgendwelche Fehler. FYI, meine Plattform ist windows 7 auf einem Tesla C2050 GPU-Karte.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Es ist ein ziemlich verbreiteter Irrtum, dass
malloc
direkt bekommt Speicherzuordnungen aus den host-Betriebssystem, wenn Sie aufgerufen, und diefree
direkt entlässt Sie zurück zu dem host-Betriebssystem, wenn Sie aufgerufen. Aber Sie fast immer nicht so arbeiten, anstatt die standard-Bibliothek hält eine zirkuläre Liste von frei würde und malloc würd Erinnerung, die opportunistisch ausgebaut und vertraglich durch die Interaktion mit dem host-OS (siehe einige Antworten auf Wie malloc() und free() arbeiten? für mehr details, wenn Sie interessiert sind). Unabhängig davon, wie es funktioniert, führt dies zu einer Reihe von nicht-intuitive Ergebnisse, einschließlich der Tatsache, dass es in der Regel nicht möglich zu reservieren, so viel Arbeitsspeicher wie das OS sagt, ist frei, dass die Zuweisungen erscheinen manchmal nicht zu ändern (die Größe des freien Speichers, und dassfree
hat manchmal keine Wirkung auf die Größe des Speichers, der OS, sagt frei.Obwohl ich nichts haben, aber empirische Beweise, dies zu unterstützen, ich glaube, CUDA funktioniert genau die gleiche Weise. Der Kontext verwaltet eine eigene Liste von malloc würde und frei würde-Speicher, und wird erweitern und Vertrag die Erinnerung statt, die in dieser Liste als host-Treiber/window-manager und die GPU selbst ermöglicht. Alle hardware hat einen charakteristischen MMU Seite Größe, und es gibt Hinweise darauf, dass die Größe der Seite, die auf NVIDIA-GPUs ist ziemlich groß. Dies bedeutet, daß es eher groben Granularität in
cudaMalloc
ruft, und das bedeutet manchmal einemalloc
scheint keinen Einfluss auf die Menge des freien Speichers oder verbrauchen viel mehr Speicher als angefordert wurde, und manchmalfree
Anrufe angezeigt haben keine Wirkung (Wenn Sie interessiert sind, können Sie ein kleines Werkzeug, das hilft, veranschaulichen die Größe der Seite Verhalten des CUDA-Treiber hier, obwohl es geschrieben wurde, für eine frühe version des CUDA-API und vielleicht müssen ein paar änderungen zu kompilieren, mit moderne Versionen). Ich glaube, dies ist die wahrscheinlichste Erklärung für das Verhalten beobachtet.Übrigens, wenn ich eine vereinfachte version des Codes, die Sie geschrieben auf MacOS 10.6 mit einem GT200-Familie Gerät:
Bekomme ich ein anderes Ergebnis, aber auch eine, die die gleichen Phänomene:
Was darauf hindeutet, dass das Verhalten der hardware - /host-OS abhängig.