4 - Utilisation de la mémoire "shared" de chaque multiprocesseur :
On repartira du code obtenu à la fin de la question 3, auquel on ajoutera un nouveau kernel (K2).
- Implantez le kernel K2 (et sa grille de blocs de threads) en version simplifiée pour que :
- chaque thread calcule un élément complet de la matrice C (matrice résultat),
- un bloc de threads soit une surface 2D carrée de threads calculant les éléméments d'une sous-matrice carrée de C,
- le kernel K3 implémente l'algorithme vu en cours utilisant la shared memory.
A ce stade, on supposera que la taille des matrices est un multiple de la taille des blocs de threads.
Testez
votre implantation sur une matrice de 4096x4096 éléments (vérifiez que vous obtenez les mêmes valeurs que sur
CPUs).
- Implantez le kernel K3 pour qu'il fonctionne même si la taille des matrices n'est plus un multiple de la taille des blocs de threads.
On continuera toutefois à considérer des matrices carrées.
Testez
votre implantation sur une matrice de 4097x4097 éléments (vérifiez que vous obtenez les mêmes valeurs que sur
CPUs).
- Mesure de performances : Une fois que votre kernel K3 est au point, mesurez les performances obtenues sur une matrice de 4096x4096 éléments.
Faites
varier la taille de vos blocs 2D de threads, et mesurer les
performances obtenues. Vérifiez toujours l'exactitude des résultats obtenus.
Comparez
aux meilleurs performances obtenues sur CPU multi-coeurs en OpenMP,
et aux meilleures performances obtenues sur GPU précédemment (sans
la mémoire "shared"). calculez les speedup GPU-shared vs CPU, et GPU-shared vs GPU.