2016-06-10 2 views
2

La fonction cudaMalloc() est defined en utilisant:Pourquoi est-il nécessaire d'effectuer un cast ** (par exemple dans les appels cudaMalloc)?

cudaMalloc ( 
    void ** devPtr, 
    size_t size) 

Les réponses here et here donner de bonnes explications pour lesquelles la fonction doit être défini pour accepter un pointeur vers un pointeur. Cependant, je suis moins clair sur la raison pour laquelle nous avons besoin de taper les arguments que nous fournissons lorsque nous appelons la fonction à type void **. Par exemple. dans l'appel à la fonction:

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

présenté here. Si je comprends bien, définir une fonction qui accepte les types void est quelque chose qui lui donne plus de flexibilité. C'est à dire. en regardant la définition de la fonction cudaMalloc(), je l'interprète comme signifiant qu'il peut accepter un pointeur vers un pointeur vers n'importe quel type d'objet. En tant que tel, pourquoi devrait-il être nécessaire de taper cast &device_array (dans l'exemple ci-dessus) lors de l'appel de la fonction. (Cette syntaxe de cette typecasting semble très répandue dans les exemples cudaMalloc() que je vois à travers le web). Tant que &device_array satisfait la condition qu'il est un "pointeur vers un pointeur de n'importe quel type de données", n'est pas suffisant pour (a) satisfaire la définition de fonction des arguments cudaMalloc() accepte et (b) accomplir tous les objectifs de programmation nous avoir?

Qu'est-ce qui me manque ici?

+4

Il est pas nécessaire. Vous n'avez plus besoin de lancer 'void **' en utilisant les versions CUDA modernes de 'cudaMalloc' - essayez-le et voyez. –

+1

Il peut accepter un pointeur vers un pointeur vers n'importe quel type d'objet, mais 'device_array' n'est pas un pointeur vers un type d'objet, c'est un pointeur vers un type particulier d'objet. – immibis

Répondre

6

La conversion en void** est toujours incorrecte car ce type n'est pas un generic pointer.

Ainsi, lorsqu'une fonction a un paramètre de type void**, le seul type d'argument qui lui est transmis peut être de type: void**, ce qui rend tout cast incorrect ou inutile.

La manière correcte (en ignorant la vérification des erreurs) d'obtenir la mémoire de cudaMalloc est:

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

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

"Passer à' void ** 'est toujours faux" - non ce n'est pas: 'void * x; void * y = & x; void * z; * (vide **) y = & z; ' – immibis