2010-12-12 32 views
3

Actuellement, CUDA n'autorise pas les noyaux imbriqués.Noyaux imbriqués dans CUDA

Pour être spécifique, j'ai le problème suivant: J'ai N nombre de données de dimension M. Pour traiter chacun des N points de données, trois noyaux doivent être exécutés dans une séquence. Depuis, l'imbrication des noyaux n'est pas autorisée, je ne peux pas créer un noyau avec des appels aux trois noyaux. Par conséquent, je dois traiter chaque point de données en série.

Une solution consiste à écrire un gros noyau contenant la fonctionnalité de tous les trois autres noyaux, mais je pense qu'il sera sous-optimal. Quelqu'un peut-il suggérer comment les flux peuvent être utilisés pour exécuter les N points de données en parallèle, tout en conservant les trois noyaux plus petits.

Merci.

+0

Quel est le problème avec un gros noyau? – Anycorn

+0

Je ne peux pas réaliser le parallélisme des grains fins. Disons que je fais trois opérations matricielles différentes sur un point de données. Je peux écrire le noyau pour chacun d'eux. En supposant que l'un des noyaux est une multiplication matricielle C = A * B. Le noyau de multiplication trouvera chaque entrée de C (i, j) en parallèle. Ce que je ne peux pas faire quand j'ai un gros noyau avec les trois opérations. Ce que fera le gros noyau, c'est de travailler avec des points de données en parallèle. – Prasanna

+0

vous pouvez certainement exécuter plusieurs flux. est assez simple, fondamentalement le 4ème paramètre au lancement du noyau est le flux. Les noyaux lancés sur le même flux s'exécuteront séquentiellement, mais les noyaux lancés sur différents flux seront exécutés dans un ordre non synchronisé. Si vous avez des questions spécifiques sur la mise en œuvre, je pourrais vous aider avec cela – Anycorn

Répondre

3

Eh bien, si vous voulez utiliser les flux ... vous voulez créer des flux N:

cudaStream_t streams; 
streams = malloc(N * sizeof(cudaStream_t)); 
for(i=0; i<N; i++) 
{ 
    cudaStreamCreate(&streams[i]); 
} 

Ensuite, pour le point de données ième, vous souhaitez utiliser cudaMemcpyAsync pour les transferts:

cudaMemcpyAsync(dst, src, kind, count, streams[i]); 

et appelez vos noyaux avec tous les paramètres de configuration quatre (SharedMemory peut être 0, bien sûr):

kernel_1 <<< nBlocks, nThreads, sharedMemory, streams[i] >>> (args); 
kernel_2 <<< nBlocks, nThreads, sharedMemory, streams[i] >>> (args); 

et de nettoyage des cours:

for(i=0; i<N; i++) 
{ 
    cudaStreamDestroy(streams[i]); 
} 
free(streams) 
0

De nos jours, avec la compatibilité de Fermi, il est possible de lancer le noyau parallèle

2

Comme une mise à jour la réponse choisie, le GPU NVidia avec Compute capacité 3.5 permet maintenant des noyaux imbriqués, Dynamic Parallelism comme ils l'appellent.