[C + CUDA] kleines Zeigerproglem

KillerPinockel

Lieutenant
Registriert
Jan. 2009
Beiträge
621
Hey,

ich habe ein kleines Problemchen, was sich sicher schnell zu lösen läst.

Mein Programm erstellt ein recht großes Array (und das ist auch so gewollt). Danach soll das Array (als Referenz) an eine Funktion übergeben werden und bspw ein paar Werte auf "1" gesetzt werden.
Wenn ich aber im Anschluss die Werte ausgebe, dann steht nur "0" drin. Hier mal der Code:

Main:
Code:
unsigned long int SIZE = 500 * 500 * 10000 
float *result;
cudaMallocHost(&result, SIZE * sizeof(float));
func(result);
.
.
.
//Einfach mal ausgeben um zu schauen, ob es funktioniert hat
int i;
for (i=0; i<10000; i++)
printf("%f \n", result[i]);

Func:
Code:
void func(float *result)
{
//10000 Werte auf "1" setzen
int i;
for (i=0; i<10000; i++)
result[i] = 1;
}

Ich weiss nicht ob es wichtig zu erwähnen ist, dass ich die Func in einer seperaten Datei (*.cu inkl *.h) liegen habe. Includiert habe ich aber alles soweit richtig.

Hoffe Ihr könnt mir beim meinem sicher kleinen Problem helfen ;)
Danke!
 
Zuletzt bearbeitet:
Nimm beim printf noch mal das & weg.
 
Und wo wird jetzt die Funktion korr aufgerufen?
 
Ich habe Zeiger (auch als Refernez) bereits in andern Funktionen genutzt und da klappt das wunderbar. Nur nicht wenn die main() und die func() in getrennten Dateien liegen :(
 
Mallocst du nicht viel zu viel Speicher? Du hast doch 10k Einträge im Array, also:

cudaMallocHost(result, 10000 * sizeof(float));

Auch hier ohne "&".
 
Ist dir bewusst wie viel Speicher du versuchst zu reservieren - fast 2,4GB! Das kann sehr wahrscheinlich nicht klappen, wenn du z.B. für 32bit kompilierst. Das kann schon das Problem sein.

Alle Cuda-Api-Calls liefern Fehlercodes zurück. Diese sind nicht dazu da um sie zu ignorieren. Würdest du ihn überprüfen, sollte da schon ein Fehler erscheinen.
 
sdwaroc schrieb:
Mallocst du nicht viel zu viel Speicher? Du hast doch 10k Einträge im Array, also:

cudaMallocHost(result, 10000 * sizeof(float));

Auch hier ohne "&".

Code:
cudaError_t cudaMallocHost (void ** ptr, size_t size)

daher sollte cudaMallocHost(&result, size) schon richtig sein. Kann bloß vielleicht etwas viel Speicher sein. Vielleicht mal Fehlercode checken.


Da ich mich aber nicht mit Cuda auskenne, kp was da passiert. Ich würde vielleicht einfachmal ein printf in "func" packen um zu gucken ob Funktion überhaupt richtig aufgerufen wird.
 
Ja gut das & bleibt also stehen, aber size_t size ist trotzdem zu groß.

Reicht es denn den Speicher auf dem Host zu Mallocen oder muss da auch noch auf der Graka passieren?
 
sdwaroc schrieb:
... muss da auch noch auf der Graka passieren?

Graka hat eigenes Malloc, cudaMallocHost ist nur für normalen Hauptspeicher und soll später dabeihelfen von Hauptspeicher zu Graka zu kopieren durch extra Funktionen.
 
sdwaroc schrieb:
Ahh ich lese gerade:



@TE: Das machst du auch?

Das braucht er nicht! CudaMallocHostnallokiert Page-Locked Memory auf dem Host. Der Host kann ganz normal den Speicher benutzen. Da er den Pointer in einer Host-Funktion verwendet und nicht in einem Kernel, passt das.
Page-Locked Speicher hat dann eben einen Geschwindigkeitsvorteil gegenüber mit new oder malloc reservierten, wenn man ihn auf die GPU kopiert.

Das Problem wird ziemlich sicher der zu viel reservierte Speicher sein.
 
Naja sollte dann nicht , wenn man "zu viel" alloziert, deshalb die Allozierung fehlschlägt, und dann drauf zugreift nen Seg-Fault kommen?

Edit: Zum Beispiel dieses Programm:
Code:
	size_t Large = 1024*1024*1024*16;
	float *Pointer;
	cudaMallocHost(&Pointer, Large);

	printf("%f",Pointer[0]);

Erzeugt:
Unhandled exception at 0x008D135C in Blah.exe: 0xC0000005: Access violation reading location 0x00000000.



Wie dem auch sei. Der Thread wird sowieso schnell im Sande verlaufen, wenn der TE wieder wie in seinem letzten Thread Geheimniskrämerei betreibt und sich hartnäckig weigert die relevanten Quelltextauszüge zu posten.
 
Zuletzt bearbeitet:
KillerPinockel schrieb:
Hey,
Code:
unsigned long int SIZE = 500 * 500 * 10000 
float *result;
cudaMallocHost(&result, SIZE * sizeof(float));
func(result);

Gewöhn dir mal bitte umgehend diesen Schön-Wetter-Programmierstil ab! Funktionen wie cudaMallocHost() können fehlschlagen. Deswegen hat die Funktion auch einen Rückgabewert vom Typ cudaError_t, der vorm Weiterarbeiten unbedingt zu überprüfen ist (cudaSuccess == alles super, cudaErrorMemoryAllocation == das war nix!).

Alternativ hättest du den Zeiger result vorher auch mit 0 vorbelegen können. Zeigt er nachher immer noch auf keine Adresse, kannst du davon ausgehen, daß die Allozierung fehlgeschlagen ist.
 
Wohin soll das ganze eigentlich führen?
 
Erweiterung zu meinem 1. Beitrag oben: So wie dein Code im Moment aussieht, zeigt result nämlich auf irgend eine x-beliebige Speicheradresse, und solle dein cudaMallocHost-Aufruf fehlschlagen, tut sie das auch danach noch. Anschließend rödelst du dann in einer for-Schleife über diesen Speicherbereich und schreibst da einfach ein paar tausend Einsen rein. Wenn das Programm nicht schon an dieser Stelle mit einem segfault Flöten geht, hast du dir gerade den Stack oder den Heap oder beides zerballert, und dein Programm befindet sich in einem nicht mehr definierten Zustand.
 
Das schien mir aber auch insgesamt ziemlich unwahrscheinlich. Denn dafür müsste man es schaffen, dass man zuerst durch "Zufall" beim Dereferenzieren keinen Seg-Fault verursacht. Dann müsste es man es zusätzlich noch schaffen, so in dem Speicherbereich des Zeigers irgendwo im Programm herumzuschreiben, dass zwar noch PrintF aufgerufen wird, jedoch es für den so eben beschriebenen Bereich nur noch 0en ausgibt.

Oder sehe ich das mit dem unwahrscheinlich falsch?
 
Zurück
Oben