CUDA : cours travaux dirigés
L'objectif du TP est de comparer les temps de calcul de différentes implantations de la fonction de Fitch qui calcule le maximum de parcimonie de deux séquences d'ADN.
On pourra s'inspirer du TP3 pour le programme à réaliser.
Dans l'exemple suivant, les données en entrée sont deux séquences x et y, et la séquence z est le résultat du calcul. On retourne le nombre de différences.
int parsimony(char *x, char *y, char *z, int size) {
int i, differences=0;
for (i = 0; i < size; i++) {
z[i] = x[i] & y[i];
if (z[i] == 0) {
z[i] = x[i] | y[i];
++differences;
}
}
return differences;
}
Le traitement à réaliser correspond à ce que l'on qualifie de réduction parallèle comme le produit scalaire.
Ecrire une première version CPU de cette fonction et la tester.
Ecrire une première version GPU de cette fonction et la tester :
On rappelle que la mémoire partagée est locale à un bloc, tous les threads d'un même bloc peuvent y accéder.
Tiré des transparents de Mark Harris (NVidia), on a ici un adressage dit séquentiel sans conflit d'accès aux bancs mémoire.
Ecrire une seconde version GPU :
On peut améliorer le traitement en évitant de coder le if, en tout cas cela fonctionne et apporte une amélioration sur le CPU :
char parsimony(char *x, char *y, char *z, int size) {
int i, differences=0;
for (i=0; i < size; ++i) {
unsigned char x_, y_;
int c;
x_ = x[i] & y[i];
y_ = x[i] | y[i];
z[i] = (x_ == 0) ? y_ : x_;
c = ((!x_) & 1);
differences += c;
}
return differences;
}