1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
| #include <pthread.h>
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include "types.h"
#include "pmat.h"
#include "mat.h"
#include "tab.h"
uint * choix; /* tableau 'choix' dans l'algo du boulanger */
uint * numero; /* tableau 'numero' dans l'algo du boulanger */
int * term; /* tableau indiquant la terminaison des taches pour le rendez-vous */
pthread_t * threads = NULL; /* tableau stockant les identifiants de chaque thread */
void * fun( void * arg )
{
uint i;
int z; /* l'indice de ma boucle */
thread_arg a;
/* On convertit l'argument 'arg' pour recuperer le bon type */
a = (thread_arg) arg;
i = a->k; /* i est egal à k ici, ca simplifie le reste */
printf("Je suis le thread numero %d, je vais faire une petite demande de calcul\n",i);
/* Algorithme du boulanger, straight from the paper */
choix[i] = 1; /* on signale qu'on demande un accès */
numero[i] = 1 + max( numero , a->m1->l ); /* on prend le numéro suivant dans le tableau des numéros */
choix[i] = 0; /* on a fini de demander un numero */
for (z = 0; z < a->m1->l; z++)
{
while (choix[z]){ /* tant que quelqun est encore dans la liste de demande, on lui laisse le passage */
}
while(numero[z] && ((numero[z]<numero[i]) || ((numero[z] == numero[i]) && (z < i))) ){
}
/* on a fini d'attendre, c'est à nous, ouf! */
}
printf("Tache %d :Je calcule r[%d][%d]= %f + (%f)*(%f)....\n",i,a->i,a->j,a->r->data[a->i][a->j],a->m1->data[a->i][a->k],a->m2->data[a->k][a->j]);
/* Debut de la section critique */
a->r->data[a->i][a->j] += (a->m1->data[a->i][a->k])*(a->m2->data[a->k][a->j]);
/* Fin de la section critique */
printf("Tache %d : Fini!\n",i);
numero[i] = 0; /* on rend notre ticket */
/* Fin de la sortie de la section critique */
return NULL;
}
/*
Fonction qui lance les threads pour effectuer le calcul parallele.
*/
mat mat_pmul( mat m1, mat m2 )
{
thread_arg targs = NULL; /* tableau des arguments des threads */
mat r = NULL;
uint i, j, k = 0;
/* On connait la taille de la matrice resultat, on alloue */
r = mat_new_zeros( m1->h, m2->l );
/* On alloue la place pour les tableaux */
threads = malloc( m1->l*sizeof( *threads ) );
targs = malloc( m1->l*sizeof( *targs ) );
choix = malloc( m1->l*sizeof( *choix ) );
numero = malloc( m1->l*sizeof( *numero ) );
term = malloc( m1->l*sizeof( *term ) );
/* Ce qui ne changera pas d'une execution sur l'autre */
for ( k= 0; k< m1->l; k++ )
{
term[k] = 0;
targs[k].m1 = m1;
targs[k].m2 = m2;
targs[k].r = r;
}
/* on double-boucle sur la matrice entiere */
for ( i= 0; i< r->h; i++ )
for ( j= 0; j< r->l; j++ )
{
/* pour chaque appel de thread a l'iteration (i,j)... */
for ( k= 0; k< m1->l; k++ )
{
term[k] = 0;
choix[k] = 0;
numero[k] = 0;
threads[k] = 0;
targs[k].i = i;
targs[k].j = j;
}
/* on lance les threads */
for ( k= 0; k< m1->l; k++ )
{
targs[k].k = k; /* il ne manquait plus que de savoir quel calcul faire */
pthread_create(&threads[k] , NULL , fun , &targs[k]);
}
/* Avant de passer au coefficient suivant, on verifie
que tous les threads ont termine...
*/
printf("Jointure des threads \n");
for ( k= 0; k< m1->l; k++ )
{
if (pthread_join(threads[k],NULL) == 0){
threads[k] = 0;
printf("Thread %d joint\n",k);
}
else{
printf("Erreur : thread %d non fini\n",k);
}
}
printf("Fin de jointure des threads, on passe au coef suivant...\n");
/* ... */
}
/* on fait le menage... */
free( targs );
free( threads );
free( numero );
free( choix );
return r;
} |
Partager