#include #include #include #include #include #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; }