2016-06-10 12 views
2

Die cudaMalloc() Funktion ist defined mit:Warum ist es notwendig, auf Void ** zu verzichten (z. B. in cudaMalloc-Calls)?

cudaMalloc ( 
    void ** devPtr, 
    size_t size) 

Die Antworten here und here gibt gute Erklärungen dafür, warum die Funktion sollte einen Zeiger auf einen Zeiger akzeptieren definiert werden.

Ich bin jedoch weniger klar, warum wir die Argumente übergeben müssen, die wir liefern, wenn wir die Funktion als Typ void ** nennen. Z.B. im Aufruf der Funktion:

catch_status = cudaMalloc((void**)&device_array, num_bytes); 

dargestellt here.

Wie ich es verstehe, ist die Definition einer Funktion, die Void-Typen akzeptiert, etwas, das ihr mehr Flexibilität gibt. I.e. Wenn ich die Definition der Funktion cudaMalloc() betrachte, interpretiere ich sie so, dass sie einen Zeiger auf einen Zeiger auf einen beliebigen Objekttyp akzeptiert. Daher sollte es notwendig sein, beim Aufruf der Funktion die Zeichenfolge &device_array (im obigen Beispiel) einzugeben. (Diese Syntax einer solchen Typumwandlung scheint in den cudaMalloc() Beispielen, die ich überall im Internet sehe, sehr weit verbreitet zu sein). Solange &device_array die Bedingung erfüllt, dass es sich um einen "Zeiger auf einen Zeiger irgendeiner Art von Daten" handelt, ist das nicht genug, um (a) die Funktionsdefinition der Argumente cudaMalloc() zu akzeptieren und (b) irgendwelche Programmierziele zu erfüllen haben?

Was fehlt mir hier?

+4

es nicht notwendig ist. Sie müssen nicht mehr mit den modernen CUDA-Versionen von 'cudaMalloc' auf" void ** "umstellen - probieren Sie es aus und sehen Sie. –

+1

Es kann einen Zeiger auf einen Zeiger auf einen beliebigen Objekttyp akzeptieren, aber 'device_array' ist kein Zeiger auf einen beliebigen Objekttyp, es ist ein Zeiger auf einen bestimmten Objekttyp. – immibis

Antwort

6

Casting zu void** ist immer falsch, da dieser Typ kein generic pointer ist.

Wenn also eine Funktion einen Parameter vom Typ void** hat, kann der einzige Typ des übergebenen Arguments vom Typ sein: void**, was jede Umwandlung falsch oder unnötig macht.

Der richtige Weg (ohne Berücksichtigung von Fehlerprüfung) des Speichers von cudaMalloc bekommen ist:

void* mem; 
cudaMalloc(&mem , num_int_bytes); 
int* array = mem; 

cudaMalloc(&mem , num_double_bytes); 
double* floating = mem; 
+3

"Casting zu' void ** 'ist immer falsch" - nein es ist nicht: 'void * x; void * y = & x; void * z; * (void **) y = & z; ' – immibis