Untitled
unknown
plain_text
2 years ago
4.2 kB
3
Indexable
Never
#include <stdio.h> #include <stdlib.h> #include <sys/time.h> #include <string.h> #include <math.h> #include <omp.h> char *help = "\n\ ** Matrix_Mult_OpenMP.c ** \n\ Inmultirea matricelor in OpenMP \n\ \n\ Se compileaza: \n\ gcc Matrix_Mult_OpenMP.c -o Matrix_Mult_OpenMP -fopenmp -lgomp \n\ \n\ Se lanseaza cu parametrii n, p, mod, max_rep \n\ Implicit n = 1024, p = 1, mod = 0, max_rep = 1 \n\ \n\ ./Matrix_Mult_OpenMP n p mod max_rep \n\ \n\ Parametrul mod este optional - implicit este 0: \n\ mod 0: Inmultire paralela cu partitionare pe linii \n\ mod 1: Inmultire paralela cu partitionare pe linii întretesute \n\ mod 2: Inmultire paralela cu partitionare pe coloane cu interschimb cu 1 regiune paralela \n\ mod 3: Inmultire paralela cu partitionare pe coloane cu n regiuni paralele \n\ mod 4: Inmultire paralela cu partitionare pe coloane cu 1 regiune paralela \n\ mod 5: Inmultire paralela cu partitionare pe blocuri cu 1 regiune paralela \n\ \n\ Se executa de max_rep ori si se mediaza timpul de executie dat in secunde \n\ care se afiseaza si se inscrie in fisierul Res_Matrix_Mult_OpenMP.txt \n"; int main(int argc, char *argv[]) { int n = 1024; // Dimensiune matrice int p = 1; // Numar thread-uri int mod = 0; // Mod 0: partitionare pe linii int max_rep = 1; // Numar de repetari ale executiei float **a, *c; // Matricele de date int i, j, k, t, f, d, rep; char *text_mod; struct timeval t1, t2; float tp; char *fn = "Res_Matrix_Mult_OpenMP.txt"; FILE *fp; // Citire parametri if (argc >= 2 && strcmp(argv[1], "-help") == 0) { printf("%s\n", help); return 0; } if (argc >= 2) n = atoi(argv[1]); if (argc >= 3) p = atoi(argv[2]); if (argc >= 4) mod = atoi(argv[3]); if (argc >= 5) max_rep = atoi(argv[4]); // Testare parametri if (n < 2) { printf("Eroare: n < 2 \n"); exit(0); } if (p < 1) { printf("Eroare: p < 1 \n"); exit(0); } if (max_rep < 1) { printf("Eroare: max_rep < 1 \n"); exit(0); } // La partitionare in blocuri: p patrat perfect, n divizibil cu sqrt(p) if (mod == 5) { if (sqrt(p) != (int)sqrt(p)) { printf("Eroare: partitionare in blocuri (mod = %d) si p nu este patrat perfect\n", mod); exit(0); } if (n % (int)sqrt(p) != 0) { printf("Eroare: partitionare in blocuri (mod = %d) si n nu este divizibil cu sqrt(p)\n", mod); exit(0); } } f = sqrt(p); d = n / f; // Alocarea datelor a = (float **)malloc(sizeof(float *) * n); c = (float *)malloc(sizeof(float) * n); for (i = 0; i < n; i++) { a[i] = (float *)malloc(sizeof(float) * n); } // Initializare matrice a, b for (i = 0; i < n; i++) for (j = 0; j < n; j++) { a[i][j] = 1; } gettimeofday(&t1, NULL); for (rep = 0; rep < max_rep; rep++) { if (p == 1) { // Inmultirea secventiala a doua matrice text_mod = "Inmultire secventiala"; for (i = 0; i < n; i++) { c[i] = 0; for (j = 0; j < n; j++) c[i] += a[i][j]; } } // Inmultirea paralela a doua matrice else if (mod == 0) { text_mod = "mod 0: Inmultire paralela cu partitionare pe linii cu 1 regiune paralela"; #pragma omp parallel num_threads(p) shared(a, c, n) private(i, j) { #pragma omp for for (i = 0; i < n; i++) { c[i] = 0; for (j = 0; j < n; j++) c[i] += a[i][j]; } } } } gettimeofday(&t2, NULL); tp = ((float)(t2.tv_sec - t1.tv_sec) + 0.000001 * (t2.tv_usec - t1.tv_usec)) / max_rep; // Scriere timp de executie in fisier fp = fopen(fn, "a"); if (p == 1) fprintf(fp, "\n%f ", tp); else fprintf(fp, "%f ", tp); fclose(fp); // Afisare timp executie mediat pe max_rep teste repetate printf("%s \n", text_mod); printf("%d rep, n = %d, p = %d, t = %f sec\n", max_rep, n, p, tp); // Afisare rezultate if (n <= 16) { for (i = 0; i < n; i++) { for (j = 0; j < n; j++) printf("%4.0f ", c[i]); printf("\n"); } } return 0; }