174 lines
No EOL
4.1 KiB
C
174 lines
No EOL
4.1 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <sys/time.h>
|
|
#include <pthread.h>
|
|
#include <unistd.h>
|
|
|
|
#define D 1000
|
|
|
|
/*
|
|
* TP 3
|
|
* 1) Fait et ok.
|
|
* 2) Fait et ok. On constate que la seconde méthode est plus longue.
|
|
* 3) Ça ne donne pas la bonne valeur : il faut proteger l'incrémentation par un mutex
|
|
* 4) On constate que le temps de'exécution augmente de manière exp.
|
|
*/
|
|
|
|
|
|
int V[D];
|
|
int V_plus[D];
|
|
int A[D][D];
|
|
int t_num = 0;
|
|
|
|
int compt_glob = 0;
|
|
|
|
|
|
void err_args() {
|
|
printf("[~] Usage: calcul [-m [1|2]] [-t #] [-i ##]\n");
|
|
printf("Aide :\n -i [ITÉRATIONS]\n -m [MÉTHODE]\n -t [THREAD] (max: 16)\n -v, verbose output\n");
|
|
exit(-1);
|
|
}
|
|
|
|
|
|
void * fn_thread_m1 (void * p_int) {
|
|
int nb_t = *(int *) p_int;
|
|
int lt = (D / nb_t) + 1;
|
|
int num = t_num;
|
|
++t_num;
|
|
|
|
for (int i = num * lt; i < (num+1)*lt && i < D; ++i){
|
|
for (int j = 0; j < D; ++j){
|
|
V_plus[i] += V[j] * A[i][j];
|
|
//compt_glob++;
|
|
}
|
|
}
|
|
|
|
pthread_exit(0);
|
|
}
|
|
|
|
void * fn_thread_m2 (void * p_int) {
|
|
int nb_t = *(int *) p_int;
|
|
int lt = (D / nb_t) + 1;
|
|
int num = t_num;
|
|
++t_num;
|
|
|
|
for (int j = 0; j < D; ++j){
|
|
for (int i = num * lt; i < (num+1)*lt && i < D; ++i){
|
|
V_plus[i] += A[i][j] * V[j];
|
|
//compt_glob++;
|
|
}
|
|
}
|
|
|
|
pthread_exit(0);
|
|
}
|
|
|
|
|
|
|
|
int main (int argc, char **argv) {
|
|
// On parse les arguments
|
|
int c;
|
|
extern char *optarg;
|
|
extern int optind;
|
|
int method = -1;
|
|
int nb_t = -1;
|
|
int ite = -1;
|
|
int v = 0; //verbose
|
|
|
|
|
|
while ((c = getopt(argc, argv, "m:t:i:v")) != -1) {
|
|
switch (c) {
|
|
case 'm':
|
|
method = atoi(optarg);
|
|
if (method != 1 && method != 2) err_args();
|
|
break;
|
|
|
|
case 't':
|
|
nb_t = atoi(optarg);
|
|
if (nb_t > 16) err_args();
|
|
break;
|
|
|
|
case 'i':
|
|
ite = atoi(optarg);
|
|
break;
|
|
|
|
case 'v':
|
|
v = 1;
|
|
break;
|
|
|
|
default:
|
|
err_args();
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (method < 0 || nb_t < 0 || ite < 0) err_args();
|
|
|
|
printf("Lancement du programme...\nMéthode %d, %d thread(s) et %d itération(s)\n", method, nb_t, ite);
|
|
|
|
//Fichier de sauvegarde
|
|
FILE* fichier = NULL;
|
|
fichier = fopen("calcul.txt", "w");
|
|
fprintf(fichier, "Méthode %d - %d thread(s) - %d itération(s)\n", method, nb_t, ite);
|
|
|
|
//On initialise les tableaux
|
|
//srand(time(NULL));
|
|
if (!v) goto no_verbose1;
|
|
srand(0);
|
|
for (int i = 0; i < D; ++i){
|
|
V[i] = (rand() % 20) - 10;
|
|
V_plus[i] = 0;
|
|
for (int j = 0; j < D; ++j)
|
|
A[i][j] = (rand() % 20) - 10;
|
|
}
|
|
|
|
printf("Tableaux initialisés : \nV(0) = [ ");
|
|
for (int i = 0; i < D; ++i)
|
|
printf("%d, ", V[i]);
|
|
printf("]\n");
|
|
|
|
printf("A = [\n");
|
|
for (int i = 0; i < D; ++i){
|
|
for (int j = 0; j < D; ++j)
|
|
printf("%d, ", A[i][j]);
|
|
printf("\n");
|
|
}
|
|
printf("]\n");
|
|
|
|
no_verbose1:
|
|
;
|
|
struct timeval begin, end;
|
|
gettimeofday(&begin, NULL);
|
|
|
|
pthread_t threads[nb_t];
|
|
for (int it = 0; it < ite; ++it){
|
|
// Lancement des threads en fonction de la méthode
|
|
for (int j = 0; j < nb_t; ++j) {
|
|
if (method == 1) pthread_create(&threads[j], NULL, fn_thread_m1, (void*) &nb_t);
|
|
else pthread_create(&threads[j], NULL, fn_thread_m2, (void*) &nb_t);
|
|
}
|
|
|
|
// On attend que tout les threads finissent leur partie
|
|
for (int i = 0; i < nb_t; ++i) pthread_join(threads[i], NULL);
|
|
for (int i = 0; i < D; ++i) {V[i] = V_plus[i]; V_plus[i] = 0;}
|
|
t_num = 0;
|
|
|
|
// On affiche le vecteur calculé
|
|
if (!v) goto no_verbose2;
|
|
printf("V(%d) = [ ", it + 1);
|
|
for (int i = 0; i < D; ++i)
|
|
printf("%d, ", V[i]);
|
|
printf("]\n");
|
|
no_verbose2:;
|
|
}
|
|
|
|
gettimeofday(&end, NULL);
|
|
printf("Time: %ld microseconds\n", ((end.tv_sec - begin.tv_sec)*1000000L + end.tv_usec) - begin.tv_usec);
|
|
printf("Nombre d'opération arithmétique : %d\n", compt_glob);
|
|
|
|
printf("Enregistrement...");
|
|
fprintf(fichier, "Temps d'exécution : %ld\n", ((end.tv_sec - begin.tv_sec)*1000000L + end.tv_usec) - begin.tv_usec);
|
|
fclose(fichier);
|
|
printf("fait.\n");
|
|
|
|
return 0;
|
|
} |