sequential.c
#include<stdio.h> #include<stdlib.h> #include<math.h> double genvv(double x){ return (x*x+pow(x,4)+pow(x,6)+exp(-x*x)+cos(x)+sin(x)+tan(x)); } int main(int argc, char **argv){ int i,n1,n2,j,jsta,jend; int iter,niter; double xi,xf,dx; double tmr; double *ar, *br; /* Do not change */ n1 = 0; n2 = 100000000; niter = 3; /* Do not change */ ar = (double*) malloc(sizeof(double)*n2); br = (double*) malloc(sizeof(double)*n2); jsta = n1; jend = n2; jsta = n1+1; jend = n2-1; xi = 0.L; xf = 1.L; dx = (xf-xi)/(double)(n2-n1-1); for(i=n1;i<n2;i++){ br[i] = xi+(double)(i-n1)*dx; ar[i] = 0.0; } for(iter=0;iter<niter;iter++){ for(j=jsta;j<jend;j++){ /* Do not change */ ar[j] = (br[j-1]+br[j+1])/4.L+br[j]/2.L+1.L/genvv(br[j]); /* Do not change */ } for(i=n1;i<n2;i++){ /* Do not change */ br[i] = ar[i]; /* Do not change */ } } tmr = 0.L; for(j=jsta;j<jend;j++){ tmr += ar[j]; } printf("tmr = %16.7f\n",tmr); free(ar); free(br); return 0; }
parallel.c
#include <stdio.h> #include <stdlib.h> #include <math.h> #include "mpi.h" #define MAX(a,b) ((a)>(b)?(a):(b)) #define MIN(a,b) ((a)>(b)?(b):(a)) #define TRUE 1 #define FALSE 0 void para_range(int n1,int n2,int nid,int myid,int *ista,int *iend){ int iwork1, iwork2; iwork1 = (n2-n1)/nid; iwork2 = (n2-n1)%nid; *ista = myid*iwork1 + n1 + MIN(myid,iwork2); *iend = *ista + iwork1; if(iwork2 > myid) (*iend) ++; } double genvv(double x) { double res = x*x + pow(x,4)+ pow(x,6)+exp(-x*x)+cos(x)+sin(x)+tan(x); return res; } int main (int argc, char **argv) { int i,n1,n2,j,jsta,jend; int iter,niter; MPI_Status istatus; int ierr, myid,nid; int iprev, inext, ista, iend; MPI_Request isd1,isd2,irv1,irv2; int itag, iroot; double xi,xf,dx; double tmr; double *ar, *br; double ptmr, tic,toc; /* do not change ------ */ n1 = 0; n2 = 100000000; niter = 3; /* do not change ------ */ ar = (double*) malloc(n2*sizeof(double)); br = (double*) malloc(n2*sizeof(double)); xi = 0.L; xf = 1.; dx = (xf-xi)/(double)(n2-n1-1); for(i=n1;i<n2;i++){ br[i] = xi+(double)(i-n1)*dx; } MPI_Init(&argc, &argv); tic = MPI_Wtime(); MPI_Comm_size(MPI_COMM_WORLD, &nid); MPI_Comm_rank(MPI_COMM_WORLD, &myid); para_range(n1,n2,nid,myid,&ista,&iend); printf("rank:%10d ista=%15d iend=%15d\n", myid, ista, iend); jsta = ista; jend = iend; if(myid==0) jsta = n1+1; if(myid == nid-1) jend = n2-1; inext = myid + 1; iprev = myid - 1; if(myid == nid-1) inext = MPI_PROC_NULL; if(myid == 0) iprev = MPI_PROC_NULL; for(i=ista;i<iend;i++){ br[i] = xi+ (double)(i-n1)*dx; } for(iter=0;iter<niter;iter++){ itag = 101; MPI_Isend(br+iend-1, 1, MPI_DOUBLE, inext, itag, MPI_COMM_WORLD, &isd1); MPI_Isend(br+ista, 1, MPI_DOUBLE, iprev, itag, MPI_COMM_WORLD, &isd2); MPI_Irecv(br+ista-1, 1, MPI_DOUBLE, iprev, itag, MPI_COMM_WORLD, &irv1); MPI_Irecv(br+iend, 1, MPI_DOUBLE, inext, itag, MPI_COMM_WORLD, &irv2); MPI_Wait(&isd1,&istatus); MPI_Wait(&isd2,&istatus); MPI_Wait(&irv1,&istatus); MPI_Wait(&irv2,&istatus); for(j=jsta;j<jend;j++){ /* not change -----{ */ ar[j] = (br[j-1]+br[j+1])/4.L + br[j]/2.L + 1.L/genvv(br[j]); /* not change -----} */ } for(i=ista;i<iend;i++){ /* not change -----{ */ br[i] = ar[i]; /* not change -----} */ } } ptmr = 0.L; for(j=jsta;j<jend;j++){ ptmr += ar[j]; } iroot = 0; MPI_Reduce(&ptmr, &tmr, 1, MPI_DOUBLE, MPI_SUM, iroot, MPI_COMM_WORLD); if(myid==0) printf("tmr = %16.6f\n",tmr); toc = MPI_Wtime(); if(myid==0) printf("%g sec\n",toc-tic); free(ar); free(br); MPI_Finalize(); }
myparallel.c
#include<stdio.h> #include<stdlib.h> #include<math.h> #include<mpi.h> double genvv(double x){ return (x*x+pow(x,4)+pow(x,6)+exp(-x*x)+cos(x)+sin(x)+tan(x)); } int main(int argc, char **argv){ int i,n1,n2,j,jsta,jend; int iter,niter; double xi,xf,dx; double tmr; double *ar, *br; /* Do not change */ n1 = 0; n2 = 100000000; niter = 3; /* Do not change */ int nprocs, myrank, q, r, asize, xspos; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &nprocs); MPI_Comm_rank(MPI_COMM_WORLD, &myrank); q = (n2-n1)/nprocs; r = (n2-n1)%nprocs; asize = myrank<r?(q+1):q; xspos = (myrank<r?(q+1)*myrank:(q*myrank+r)) + n1; ar = (double*) malloc(sizeof(double)*(asize+2)); br = (double*) malloc(sizeof(double)*(asize+2)); jsta = 0; jend = jsta + asize; if(myrank == 0) jsta = jsta+1; if(myrank == nprocs-1) jend = jend-1; xi = 0.L; xf = 1.L; dx = (xf-xi)/(double)(n2-n1-1); for(i=0;i<asize;i++){ br[i+1] = xi+(double)(i-n1+xspos)*dx; ar[i+1] = 0.0; } MPI_Request req[4]; MPI_Status stat[4]; for(iter=0;iter<niter;iter++){ if(myrank < nprocs-1){ MPI_Isend(&br[asize], 1, MPI_DOUBLE, myrank+1, 123, MPI_COMM_WORLD, &req[0]); MPI_Irecv(&br[asize+1], 1, MPI_DOUBLE, myrank+1, 321, MPI_COMM_WORLD, &req[1]); } if(myrank > 0){ MPI_Isend(&br[1], 1, MPI_DOUBLE, myrank-1, 321, MPI_COMM_WORLD, &req[2]); MPI_Irecv(&br[0], 1, MPI_DOUBLE, myrank-1, 123, MPI_COMM_WORLD, &req[3]); } if(myrank < nprocs-1){ MPI_Waitall(2, req, stat); } if (myrank > 0){ MPI_Waitall(2, req+2, stat+2); } for(j=jsta+1;j<jend+1;j++){ /* Do not change */ ar[j] = (br[j-1]+br[j+1])/4.L+br[j]/2.L+1.L/genvv(br[j]); /* Do not change */ } for(i=1;i<asize+1;i++){ /* Do not change */ br[i] = ar[i]; /* Do not change */ } } tmr = 0.L; int cnt = 0; for(j=jsta+1;j<jend+1;j++){ tmr += ar[j]; cnt++; } double tot; MPI_Reduce(&tmr, &tot, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); if(!myrank) printf("tmr = %16.7f\n",tot); free(ar); free(br); MPI_Finalize(); return 0; }
'Parallel Programming' 카테고리의 다른 글
KSC 2015 3번 문제 및 풀이 (0) | 2016.10.01 |
---|---|
KSC 2015 2번 문제 및 답안 (0) | 2016.10.01 |
KSC 2014 3번 문제 및 답안 (0) | 2016.10.01 |
KSC 2014 2번 문제 및 답안 (0) | 2016.10.01 |
KSC 2014 1번 문제 및 답안 (0) | 2016.10.01 |
댓글