Untitled

mail@pastecode.io avatar
unknown
plain_text
2 years ago
3.6 kB
3
Indexable
Never
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <omp.h>
#include <sys/time.h>

char* help = "\n\
   ** Reduction_OpenMP.c ** \n\
   Adunarea vectorilor in OpenMP \n\
   \n\
   Se compileaza: \n\
   gcc Reduction_OpenMP.c -o Reduction_OpenMP -fopenmp -lgomp  \n\
   \n\
   Se lanseaza cu parametrii n, p, mod max_rep unde mod: 0 cu clauza reduction, mod = 1: cu clauza critical \n\
   Implicit n = 1024, p = 1,  mod = 0, max_rep = 1  \n\
   \n\
   ./Reduction_OpenMP n p mod max_rep \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_Reduction_OpenMP.txt \n";


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

        int n = 1024;				// Variabila partajata dimensiune matrice
        int p = 1;				// Variabila partajata numar thread-uri
        int mod = 0;				// Mod 0: cu clauza reduction			
        int max_rep = 1;			// Numar de repetari ale executiei
	
  	int i, q, rep;	

        float *a,*b;				// Vectorul partajat

        double sum;				// Suma totala
        double psum;				// Suma partiala (locala)

     	struct timeval t1, t2;	
     	float tp;   
    	char *fn = "Res_Reduction_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);
        }

        // Alocarea datelor
	a = (float*)malloc(sizeof(float)*n);          
   	b = (float*)malloc(sizeof(float)*n);		
 	// Initializarea vectorului de date   
         
        for (i = 0; i < n; i++) {
            a[i] = 1;
            b[i] = 1;
        }
        gettimeofday(&t1, NULL);
     
    for (rep = 0; rep < max_rep; rep++) 
    {
        sum = 0.0;
        if (p == 1) {
             // Reducerea secventiala
   	     for (i = 0; i < n; i++) 
 	        sum += a[i]*b[i];
        }
        else if (mod == 0)   
            // Reducerea paralela cu clauza reduction             
	    #pragma omp parallel num_threads(p) shared(a, b,sum) private(i)
	    {
                 #pragma omp for reduction(+:sum) nowait
		 for(i = 0; i < n; i++)
                     sum += a[i]*b[i];
	    }
        else if (mod == 1) 
            // Reducerea paralela cu clauza critical
	    #pragma omp parallel num_threads(p) shared(a,b,sum) private(i, psum)
	    {
                 psum = 0.0;
                 #pragma omp for nowait
		 for(i = 0; i < n; i++)
                     psum += a[i]*b[i];
                 #pragma omp critical
                     sum += psum;
	    }
        else {
            printf("Eroare mod = %d - inexistent\n", mod);
            exit (0);
        }
    }   // end for (rep)

	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
        printf("%d rep, sum = %f, mod = %d, n = %d, p = %d, t = %f sec\n", max_rep, sum, mod, n, p, tp);
    
        return 0; 
}