/*Questo programma calcola un valore approssimato di P greco utilizzando il metodo un algoritmo parallelo. Richiede l'inserimento di un numero, il quale indica la quantità di rettangoli usati nel calcolo. Più il numero di rettangoli è alto più il calcolo del p greco sarà preciso. Per evidenziare l'errore generato nel calcolo,abbiamo inserito il numero P greco puro, e mediante una sottrazione tra il P greco puro e il P greco calcolato otterremo l'errore.*/ #include "mpi.h" #include #include double f(double); //Dichiarazione del prototipo della funzione double f(double a) { return (4.0 / (1.0 + a*a)); } int main(int argc,char *argv[]) { int done = 0, n, myid, numprocs, i; double PI25DT = 3.141592653589793238462643; double mypi, pi, h, sum, x; double startwtime = 0.0, endwtime; int namelen; char processor_name[MPI_MAX_PROCESSOR_NAME]; MPI_Init(&argc,&argv); //chiamata alla funzione MPI_int che informa //il sistema operativo che si sta eseguendo un programma MPI MPI_Comm_size(MPI_COMM_WORLD,&numprocs); //funzione che restituisce il numero totale di processi allocati MPI_Comm_rank(MPI_COMM_WORLD,&myid); //funzione che restituisce il numero del processo che l’ha chiamata. if (argc<=1) { //Controlla se abbiamo inserito il numero di rettangoli printf("Insert the parametres\n"); //altrimenti chiude il programma con un messaggio di errore fflush(stdout); MPI_Finalize; return 0; } else n = atoi(argv[1]); //Variabile contenente il numero di rettangoli definito dall'utente fprintf(stdout,"Process %d of %d is on %s\n", myid, numprocs, processor_name); fflush(stdout); if (myid == 0) //Controllo se nessun processo è stato startwtime = MPI_Wtime(); //ancora avviato,avvia il conteggio del tempo MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD); //Funzione che manda all'anello i dati da calcolare //&n numero rettangoli,MPI_INT numero del processo,MPI_COMM_WORLD a //chi mandare il mesdsaggio per il calcolo in questo caso a tutti h = 1.0 / (double) n; sum = 0.0; //metodo migliore per il conteggio for (i = myid + 1; i <= n; i += numprocs) //inizia dal valore più grande e poi retrocede { x = h * ((double)i - 0.5); sum += f(x); } mypi = h * sum; MPI_Reduce(&mypi, &pi, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); //Funzione che riceve dall'anello i dat calcolati //&myip da chi viene ricevuto il dato,&pi in numero del p greco parziale, //MPI_DOUBLE di che tipo è la variabile,MPI_SUM fa la somma di tutti i dati ricevuti //MPI_COMM_WORLD da chi riceve i dati if (myid == 0) { //cotrolla se i processi avviati sono stati tutti endwtime = MPI_Wtime(); //conclusi e poi blocca il tempo printf("pi is approximately %.16f, Error is %.16f\n", //stampa a video dei dati calcolati e dell'errore pi, fabs(pi - PI25DT)); printf("wall clock time = %f\n", endwtime-startwtime); //stampa a video del tempo usato per il calcolo fflush(stdout); } MPI_Finalize(); //Chiusura della funzione che informa il sistema operativo di un programma MPI return 0; }