/* Program pi_scale.c */ #include "mpi.h" #include #include static inline int max(int a, int b) { return a > b ? a : b; } int main( int argc, char *argv[] ) { int n, myid, numprocs, i, j, nt; double PI25DT = 3.141592653589793238462643; double mypi, pi, h, sum, x; double t_start, t_endpar, t_endcom, t_endser; double res, speedup, s_Amdahl; MPI_Init(&argc,&argv); MPI_Comm_size(MPI_COMM_WORLD,&numprocs); MPI_Comm_rank(MPI_COMM_WORLD,&myid); double t_all[numprocs]; double t_par[numprocs]; double t_com[numprocs]; double t_ser[numprocs]; while (1) { if (myid == 0) { printf("Enter the number of intervals: (0 quits) "); scanf("%d",&n); } MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD); if (n == 0) break; else { h = 1.0 / (double) n; for (j = -3; j < numprocs; j++) { /* negative j's are serial warm-ups */ nt = max(0,j) + 1; t_start = MPI_Wtime(); sum = 0.0; if (myid < nt) { for (i = myid + 1; i <= n; i += nt) { x = h * ((double)i - 0.5); sum += (4.0 / (1.0 + x*x)); } } mypi = h * sum; t_endpar = MPI_Wtime(); MPI_Reduce(&mypi, &pi, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); t_endcom = MPI_Wtime(); if (myid == 0) { printf("%3d tasks: ", nt); printf("pi is approximately %.16f, ", pi); printf("Error is %.16f\n", fabs(pi - PI25DT)); t_endser = MPI_Wtime(); t_all[nt-1] = t_endser - t_start; t_par[nt-1] = t_endpar - t_start; t_com[nt-1] = t_endcom - t_endpar; t_ser[nt-1] = t_endser - t_endcom; } } } if (myid == 0) { res = MPI_Wtick(); printf("Clock resolution is %.10f\n", res); printf(" nt t_all t_par t_com"); printf(" t_ser speedup s_Amdahl\n"); for (j = 0; j < numprocs; j++) { speedup = t_all[0]/t_all[j]; s_Amdahl = t_all[0]/(t_ser[0] + t_com[0] + t_par[0]/(double)(j+1)); printf("%3d %12.9f %12.9f %12.9f %12.9f", j+1, t_all[j], t_par[j], t_com[j], t_ser[j]); printf("%11.4f %11.4f\n", speedup, s_Amdahl); } } } MPI_Finalize(); return 0; }