Bonjour à tous,

Je viens poser ma question ici car je ne sais pas pourquoi mon programme plante sous Mac, alors que sous Linux il fonctionne à merveille.

Voilà le topo: j'utilise la librairie pthread pour faire un calcul en parallele des coeficients d'une matrice, qui est la multiplication de 2 autres matrices.

Pour chaque r(i,j) de la matrice, on fait la somme des a(i,k) * b(k,j) (multiplication d'une matrice quoi...).
J'ai donc lancé un thread pour CHAQUE indice k, afin de faire chaque multiplication a(i,k) * b(k,j) (ca fait donc plein de threads juste pour r(i,j)).
J'utilise un algorithme du Boulanger pour éviter que mes threads mettent le boxon.

Maintenant, j'ai fini de coder, et je compile sans probleme, que ce soit sur mon macbook ou sur les machines linux de mon école (dont des bi processeurs). Problème : le code s'execute sans problème sous Linux, mais plante sous Mac.

Alors je me pose la question: est-ce que la librairie pthread a un subtilité sous mac que je ne connais pas?
Ou alors mon algorithme du boulanger foire sous mac, à cause d'une autre subtilité que je ne connais pas non plus?
Je m'en remet à vous, merci à ceux qui se plongeront dans le code!

Voilà le code incriminé:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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; 
}