Benchmark
 All Classes Files Functions Variables Typedefs Macros
Classes | Macros | Typedefs | Functions
amdahl.c File Reference
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <err.h>
#include <unistd.h>
#include <sys/wait.h>
#include "benchmark.h"

Classes

struct  scanargs
 Sert à stocker les arguments passés aux threads. More...
 
struct  result
 Sert à stocker les valeurs de retour des threads. More...
 

Macros

#define NTHREAD   32
 Nombre max de threads/processus à utiliser. More...
 
#define NLENGTH   64000
 Taille du tableau à tester. More...
 

Typedefs

typedef struct scanargs scanargs
 Sert à stocker les arguments passés aux threads. More...
 
typedef struct result result
 Sert à stocker les valeurs de retour des threads. More...
 

Functions

int primeFactors (int n)
 Calcul les facteurs premiers de n More...
 
void * scan (void *param)
 Calcul les facteurs premiers dans une portion de tableau de Integer. More...
 
int main (int argc, char *argv[])
 Enregistre les temps de calcul nécessaire à le nombre avec le plus de facteurs premiers. More...
 

Macro Definition Documentation

#define NLENGTH   64000

Taille du tableau à tester.

#define NTHREAD   32

Nombre max de threads/processus à utiliser.

Typedef Documentation

typedef struct result result

Sert à stocker les valeurs de retour des threads.

result est la structure utilisé pour stocker les valeurs renvoyés par les avec pthread_exit() . count est le nombre max de facteurs premiers qu'un thread a trouvé pour une valeur du tableau et index est l'index de cette valeur dans array .

typedef struct scanargs scanargs

Sert à stocker les arguments passés aux threads.

scanargs est la structure utilisé pour faire passer les arguments aux threads. start est l'index du premier élement du tableau array que dois scaner le thread, et stop en est le dernier.

Function Documentation

int main ( int  argc,
char *  argv[] 
)

Enregistre les temps de calcul nécessaire à le nombre avec le plus de facteurs premiers.

On va tester la loi d'Amdahl et donc vérifier l'avantage au niveau de la vitesse gagner grâce à la parallelisation d'un code CPU intensif tel que la recherche du nombre ayant la plus de facteurs premiers dans un tableau de valeurs aléatoires. La recherche est faite avec 1 puis 2 puis 3 etc... threads/processus, avec à chaque fois le temps nécessaire enregistrer dans un fichier .csv puis afficher à la fin sous forme de graphe.

155  {
156 
157  timer *t = timer_alloc();
158  recorder *thread_rec = recorder_alloc("thread.csv");
159  recorder *proc_rec = recorder_alloc("proc.csv");
160  // on init tous les `recorders` et le timer
161 
162  srand (1337);
163  int* array = (int*)malloc(sizeof(int)*NLENGTH);
164  if (array == NULL) err(1,"erreur malloc");
165  int i;
166  for (i=0; i<NLENGTH; i++) {
167  array[i] = rand() % NLENGTH;
168  }
169  // on génère le tableau de int aléatoires
170 
171 
172  /*
173  * _______ _ _
174  * |__ __| | | |
175  * | | | |__ _ __ ___ __ _ __| |___
176  * | | | '_ \| '__/ _ \/ _` |/ _` / __|
177  * | | | | | | | | __/ (_| | (_| \__ \
178  * |_| |_| |_|_| \___|\__,_|\__,_|___/
179  */
180 
181  for (i = 1; i<=NTHREAD; i=i+1) {
182  start_timer(t);
183  // on lance le chronomètre
184  int error = 0;
185 
186  pthread_t* threads = (pthread_t*)malloc(sizeof(pthread_t)*i);
187  if (threads == NULL) err(1,"erreur malloc");
188  scanargs** args = (scanargs**)malloc(sizeof(scanargs*)*i);
189  if (args == NULL) err(1,"erreur malloc");
190  result* res[i];
191  // init des tableaux d'arguments, de threads, et de resultats
192 
193  int j;
194  for (j=0; j<i; j++) {
195  args[j] = (scanargs*)malloc(sizeof(scanargs));
196  if (args[j] == NULL) err(1,"erreur malloc");
197  args[j]->start = j*(NLENGTH/i);
198  args[j]->stop = (j+1)*(NLENGTH/i)-1;
199  args[j]->array = array;
200  // remplissage de la structure argument avec le segment à scanner par le thread
201  error = pthread_create(&threads[j],NULL,&scan,(void*)args[j]);
202  if(error!=0) err(error,"erreur create");
203  // lancement du thread
204  }
205 
206  for (j=0; j<i; j++) {
207  error=pthread_join(threads[j],(void**)&res[j]);
208  if(error!=0) err(error,"erreur create");
209  // join du thread et réception de la structure resultat
210  }
211 
212  /*
213  * Analyse des resultats de tous les threads
214  */
215  int index = -1;
216  int max = 0;
217  for (j=0; j<i; j++) {
218  if (max<res[j]->count) {
219  max = res[j]->count;
220  index = res[j]->index;
221  free(res[j]);
222  free(args[j]);
223  }
224  }
225 
226  printf("%d\n",index);
227  write_record_n(thread_rec,i,stop_timer(t),NTHREAD);
228  //sauvegarde du temps
229 
230  free(threads);
231  free(args);
232  }
233 
234  puts("proc");
235 
236  /*
237  * _____
238  * | __ \
239  * | |__) | __ ___ ___ ___ ___ ___ ___ ___
240  * | ___/ '__/ _ \ / __/ _ \/ __/ __|/ _ \/ __|
241  * | | | | | (_) | (_| __/\__ \__ \ __/\__ \
242  * |_| |_| \___/ \___\___||___/___/\___||___/
243  *
244  *
245  * Meme chose que les threads mais avec des processus cette fois ci
246  */
247 
248  for (i = 1; i<=NTHREAD; i=i+1) {
249 
250  start_timer(t);
251  int error = 0;
252  pid_t pid[i];
253  int fd[i][2];
254 
255  int j;
256  for (j=0; j<i; j++) {
257  int start = j*(NLENGTH/i);
258  int stop = (j+1)*(NLENGTH/i)-1;
259  // on définit le segment à scanner
260  pipe(fd[j]);
261  // on init le pipe entre le père et fils. Il sert à ce que le fils renvoie sa réponse au père
262  pid[j] = fork();
263 
264  if (pid[j] == 0) {
265  // on est dans le fils
266  int k,p,index,count=0;
267  for (k = start; k<=stop; k++) {
268  p = primeFactors(array[k]);
269  //printf("number: %d ; primes: %d ; index: %d\n", args->array[i],p,i);
270  if (p>count) {
271  count = p;
272  index = k;
273  }
274  }
275 
276  //printf("index: %d count: %d\n",index,count);
277 
278  index = index*1000;
279  index += count;
280  // vu qu'on a 2 int à renvoyer, on les combine en 1 int à déchiffre par le père
281  //printf("index: %d\n",index);
282 
283  close(fd[j][0]);
284  write(fd[j][1], &index, sizeof(index));
285  // envoie de la réponse par pipe
286  close(fd[j][1]);
287 
288  exit(0);
289  } else if (pid[j] < 0) {
290  err(-1,"erreur de fork");
291  }
292  }
293  int max = 0,index,ret;
294  for (j=0; j<i; j++) {
295 
296  close(fd[j][1]);
297  read(fd[j][0], &ret, sizeof(ret));
298  //réception de la réponse des fils
299  close(fd[j][0]);
300 
301  pid[j] = waitpid(pid[j],NULL,0);
302  if(pid[j]<1)err(-1,"erreur waitpid");
303  //printf("ret: %d\n",ret);
304  //analyse des résultats
305  if (max < ret%1000) {
306  max = ret%1000;
307  index = ret/1000;
308  }
309  }
310 
311  printf("%d\n",index);
312  /*
313  *int it = i;
314  *int numCPU = sysconf( _SC_NPROCESSORS_ONLN );
315  *if (it > numCPU ) it = numCPU;
316  */
317  write_record_n(proc_rec,i,stop_timer(t),NTHREAD);
318  // ecriture du temps
319  }
320 
321  recorder_free(thread_rec);
322  recorder_free(proc_rec);
323  timer_free(t);
324  free(array);
325  // free de nos structures
326 }
#define NLENGTH
Taille du tableau à tester.
Definition: amdahl.c:17
Sert à stocker les valeurs de retour des threads.
Definition: amdahl.c:51
int start
Definition: amdahl.c:37
void timer_free(timer *t)
Retourne le temps en nanosecondes depuis le début de mesure dans t
Definition: benchmark.c:172
#define NTHREAD
Nombre max de threads/processus à utiliser.
Definition: amdahl.c:16
recorder écrit les temps dans un fichier .csv
Definition: benchmark.c:208
int * array
Definition: amdahl.c:39
void write_record_n(recorder *rec, long int x, long int time, long n)
Comme write_record mais divise time par n après avoir retiré l'overhead
Definition: benchmark.c:253
int count
Definition: amdahl.c:52
timer permet de mesurer le temps écoulé entre deux moments
Definition: benchmark.c:43
int stop
Definition: amdahl.c:38
timer * t
Definition: memfork.c:25
Sert à stocker les arguments passés aux threads.
Definition: amdahl.c:36
int i
Definition: mutsem.c:43
int primeFactors(int n)
Calcul les facteurs premiers de n
Definition: amdahl.c:75
void start_timer(timer *t)
Stoque le temps actuel comme début de la mesure dans t
Definition: benchmark.c:87
recorder * recorder_alloc(char *filename)
Alloue un recorder
Definition: benchmark.c:219
void * scan(void *param)
Calcul les facteurs premiers dans une portion de tableau de Integer.
Definition: amdahl.c:114
void recorder_free(recorder *rec)
Libère toutes les resources utilisées par rec
Definition: benchmark.c:263
timer * timer_alloc()
Alloue un timer
Definition: benchmark.c:63
int index
Definition: amdahl.c:53
long int stop_timer(timer *t)
Retourne le temps en nanosecondes depuis le début de mesure dans t
Definition: benchmark.c:133
int primeFactors ( int  n)

Calcul les facteurs premiers de n

Parameters
nLe nombre duquel on veut trouver les facteurs premiers
Returns
Le nombre de facteurs premiers trouvé

Calcul les facteurs premiers de n par la methode de brute force

75  {
76  int i,count=0;
77  for(i=2;i<=n;i++)
78  {
79  if(n%i==0)
80  {
81  count++;
82  n=n/i;
83  i--;
84  if(n==1)
85  break;
86  }
87  }
88  return count;
89 }
int i
Definition: mutsem.c:43
void* scan ( void *  param)

Calcul les facteurs premiers dans une portion de tableau de Integer.

Parameters
paramStructure scanargs contenant le tableau a scanner et les index de la portion à scanner
Returns
Une structure result contenant l'index du nombre avec le plus de facteurs premiers et le nombre de ces facteurs

Fonction à faire passer à un thread. Scan une portion d'un tableau à la du nombre avec le plus de facteurs premiers, et renvois cette valeur ainsi que l'index où se trouve ce nombre.

114  {
115  scanargs* args = (scanargs*)param;
116  result *res = (result*)malloc(sizeof(result));
117  res->count = 0;
118  res->index = 0;
119 
120  int i,p;
121  for (i = args->start; i<=args->stop; i++) {
122  p = primeFactors(args->array[i]);
123  //printf("number: %d ; primes: %d ; index: %d\n", args->array[i],p,i);
124  if (p>res->count) {
125  res->count = p;
126  res->index = i;
127  }
128  }
129  pthread_exit((void*)res);
130 }
Sert à stocker les valeurs de retour des threads.
Definition: amdahl.c:51
int start
Definition: amdahl.c:37
int * array
Definition: amdahl.c:39
int count
Definition: amdahl.c:52
Sert à stocker les arguments passés aux threads.
Definition: amdahl.c:36
int i
Definition: mutsem.c:43
int primeFactors(int n)
Calcul les facteurs premiers de n
Definition: amdahl.c:75
int index
Definition: amdahl.c:53