:
SISD (Single Instruction Stream - Single Data Stream) ;
SIMD (Single Instruction Stream Multiple Data Stream) ;
MISD (Multiple Instruction Stream Single Data Stream) ;
MIMD (Multiple Instruction Stream Multiple Data Stream)
MISD
. , , . . ,
MIMD
, . , , .. , , .
2.MPI , ә .
MPI , . mpicc( ), mpic++( ++), mpif77/mpif90( 77/90). -oname name , a.out, : mpif77 oprogramprogram.f
. MPI mpirun,mpiexec, :
mpirun npN< >
mpiexec npN< >
N- , . , .
3.- әң ү. 2 ө ң 1 ө ( - ә).
constint N=100;
float P[N][N],
h=0.01, //
eps=0.01, //
max, //
**p, //
**pp, //
|
|
a[N],b[N]; //
inti,j,
c, //-
stop = 1; //
intrank,size;
MPI_Init(&argc,&argv);
MPI_Status status;
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Comm_size(MPI_COMM_WORLD,&size);
if(rank<N%size)
{
c=N/size+1;
}else
{
c=N/size;
}
p=newfloat*[c];
pp=newfloat*[c];
for(i=0;i<c;i++)
{
p[i]=newfloat[N];
pp[i]=newfloat[N];
p[i][0]=1;
pp[i][0]=1;
for(int j=1;j<N;j++)
{
p[i][j]=0;
pp[i][j]=0;
}
}
if(rank==0) {
do {
if(size>1) {
MPI_Send(&p[c-1][0],N,MPI_FLOAT,rank+1,
0,MPI_COMM_WORLD);
MPI_Recv(a,N,MPI_FLOAT,rank+1,size,
MPI_COMM_WORLD, &status);
}max=0.0;
for(i=1;i<c-1;i++) {
for(j=1;j<N-1;j++) {
p[i][j]=(pp[i+1][j]+p[i-1][j]+pp[i][j+1]+p[i][j-1])/4;
if(max<fabs(p[i][j]-pp[i][j])) {
max=fabs(p[i][j]-pp[i][j]); }}}
if(size>1) {
for(j=1;j<N-1;j++) {
p[c-1][j]=(p[c-2][j]+a[j]+pp[c-1][j+1]+p[c-1][j-1])/4;
if(max<fabs(p[c-1][j]-pp[c-1][j])) {
max=fabs(p[c-1][j]-pp[c-1][j]); } }
Float maxx;
for(i=1;i<size;i++) {
MPI_Recv(&maxx,1,MPI_FLOAT,i,2*size,MPI_COMM_WORLD,&status);
if(maxx>max) {
max=maxx; } } }
if(max<=eps) {
stop=0; }
if(size>1) {
for(i=1;i<size;i++) {
MPI_Send(&stop,1,MPI_INT,i,3*size,MPI_COMM_WORLD); } }
for(i=0;i<c;i++) {
for(j=0;j<N;j++) {
pp[i][j]=p[i][j]; } }}
while(stop==1);
for(i=0;i<c;i++) {
for(int j=0;j<N;j++) {
P[i][j]=p[i][j]; } }
if(size>1) {
intjj=c-1;
for(i=1;i<size;i++) {
MPI_Recv(&c,1,MPI_INT,i,4*size,MPI_COMM_WORLD,&status);
for(j=0;j<c;j++) {
jj++; MPI_Recv(&P[jj][0],100,MPI_FLOAT,i,5*size,MPI_COMM_WORLD,&status); } } }
ofstream out("result.txt");
for(i=0;i<N;i++){
for(int j=0;j<N;j++){
out<<P[i][j]<<'\t'; //
} out<<'\n'; }}
if(rank==size-1&&size>1) {
do {
MPI_Recv(b,N,MPI_FLOAT,rank-1,0,MPI_COMM_WORLD,&status);
MPI_Send(&p[0][0],N,MPI_FLOAT,rank-1,size,MPI_COMM_WORLD); max=0;
for(i=1;i<c-1;i++) {
for(j=1;j<N-1;j++) {
p[i][j]=(pp[i+1][j]+p[i-1][j]+pp[i][j+1]+p[i][j-1])/4;
if(max<fabs(pp[i][j]-p[i][j])) {
max=fabs(pp[i][j]-p[i][j]); } } }
for(j=1;j<N-1;j++) {
p[0][j]=(pp[1][j]+b[j]+pp[0][j+1]+p[0][j-1])/4;
if(max<fabs(pp[0][j]-p[0][j])) {
max=fabs(pp[0][j]-p[0][j]); } }
MPI_Send(&max,1,MPI_FLOAT,0,2*size,MPI_COMM_WORLD);
for(i=0;i<c;i++) {
for(j=0;j<N;j++) {
pp[i][j]=p[i][j]; } }
MPI_Recv(&stop,1,MPI_INT,0,3*size,MPI_COMM_WORLD,&status);
}while(stop==1);
MPI_Send(&c,1,MPI_INT,0,4*size,MPI_COMM_WORLD);
for(i=0;i<c;i++) {
MPI_Send(&p[i][0],N,MPI_FLOAT,0,5*size,MPI_COMM_WORLD); } }
if(rank>0&&rank<size-1) {
do {
MPI_Recv(b,N,MPI_FLOAT,rank-1,0,MPI_COMM_WORLD,&status);
MPI_Send(&p[c-1][0],N,MPI_FLOAT,rank+1,0,MPI_COMM_WORLD);
MPI_Recv(a,N,MPI_FLOAT,rank+1,size,MPI_COMM_WORLD,&status);
MPI_Send(&p[0][0],N,MPI_FLOAT,rank-1,size,MPI_COMM_WORLD);
max=0; int ii;
if(rank<N%size||100%size==0) {
ii=rank*c; }
if(rank>N%size&&100%size!=0) {
ii=(N%size)*(c+1)+(rank-N%size)*c; }
for(i=1;i<c-1;i++) {
for(j=1;j<N-1;j++) {
p[i][j]=(pp[i+1][j]+p[i-1][j]+pp[i][j+1]+p[i][j-1])/4;
|
|
if(max<fabs(pp[i][j]-p[i][j])) {
max=fabs(pp[i][j]-p[i][j]); } } }
for(j=1;j<N-1;j++) {
p[0][j]=(pp[1][j]+b[j]+pp[0][j+1]+p[0][j-1])/4;
if(max<fabs(pp[0][j]-p[0][j])) 1111{
max=fabs(pp[0][j]-p[0][j]); }
p[c-1][j]=(p[c-2][j]+a[j]+pp[c-1][j+1]+p[c-1][j-1])/4;
if(max<fabs(pp[c-1][j]-p[c-1][j])) {
max=fabs(pp[c-1][j]-p[c-1][j]); } }
MPI_Send(&max,1,MPI_FLOAT,0,2*size,MPI_COMM_WORLD);
for(i=0;i<c;i++) {
for(j=0;j<N;j++) { pp[i][j]=p[i][j]; } }
MPI_Recv(&stop,1,MPI_INT,0,3*size,MPI_COMM_WORLD,&status);
}while(stop==1);
MPI_Send(&c,1,MPI_INT,0,4*size,MPI_COMM_WORLD);
for(i=0;i<c;i++) {
MPI_Send(&p[i][0],N,MPI_FLOAT,0,5*size,MPI_COMM_WORLD);} }
1. ? ғ ? ғ ғ.
MPI , , MIMD. , , . MPI. , MPI . , MPI. MPI . . `` '' (`` thread-safe''). MPI , MPI, ; MPI , . MPI . , . ; , ; . , MPI ( ), . , , . . 0,..., groupsize-1.
2.MPI- ғ. MPI_Barrier() .
. , , . , , .
. - , , , , ( ) =>intMPI_Barrier(MPI_Commcomm) - , comm . MPI_Barrier, . , , , . , , . .
|
|
3.3 ө ң 3-ө ә .
enum {UP,DOWN,LEFT,RIGHT,FRONT,BACK};
int main(intargc, char *argv[])
{
intrank,size;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Status status;
intndims=3, reorder=0;
int dims[3]={0,0,0}, periods[3]={0,0,0},coords[3],nbrs[6];
MPI_Dims_create(size, ndims, dims);
MPI_Commcartcomm;
MPI_Cart_create(MPI_COMM_WORLD,ndims,dims,periods,reorder,&cartcomm);
MPI_Comm_rank(cartcomm, &rank);
MPI_Cart_coords(cartcomm, rank, 3, coords);
MPI_Cart_shift(cartcomm,0,1,&nbrs[LEFT], &nbrs[RIGHT]);
MPI_Cart_shift(cartcomm,1,1,&nbrs[DOWN], &nbrs[UP]);
MPI_Cart_shift(cartcomm,2,1,&nbrs[FRONT], &nbrs[BACK]);
inta,b,c,i,j,k,it,nit=100,n=12;
a=n/dims[0]+2;
b=n/dims[1]+2;
c=n/dims[2]+2;
float u1[a][b][c],u0[a][b][c];
float h=1.0/n,x,y,z;
for (i=0; i<a; i++) { for (j=0; j<b; j++) { for (k=0; k<c; k++) { u0[i][j][k]=0; u1[i][j][k]=0; if (nbrs[RIGHT]==-1) {u0[a-2][j][k]=1;} } } }
for (it=0; it<nit; it++)
{
for (i=1; i<a-1; i++) { for (j=1; j<b-1; j++) { for (k=1; k<c-1; k++) {
u1[i][j][k]=(u0[i-1][j][k]+u0[i+1][j][k]+u0[i][j-1][k]+u0[i][j+1][k]+u0[i][j][k-1]+u0[i][j][k+1])/6.0; } } }
MPI_Datatype UD;
MPI_Type_vector(a-2,c-2,b*c,MPI_FLOAT,&UD);
MPI_Type_commit(&UD);
MPI_Send(&u1[1][1][1],1,UD,nbrs[UP],1,MPI_COMM_WORLD);
MPI_Recv(&u1[1][b-1][1],1,UD,nbrs[DOWN],1,MPI_COMM_WORLD, &status);
MPI_Send(&u1[1][b-2][1],1,UD,nbrs[DOWN],2,MPI_COMM_WORLD);
MPI_Recv(&u1[1][0][1],1,UD,nbrs[UP],2,MPI_COMM_WORLD, &status);
MPI_Type_free (&UD);
int count=(b-2)*(a-2),p;
intaob[count],aod[count];
for (j=0; j<count; j++) {aob[j]=1; p=j/(b-2); aod[j]=c*(j+2*p); }
MPI_Datatype FB;
MPI_Type_indexed(count,aob,aod,MPI_FLOAT,&FB);
MPI_Type_commit(&FB);
MPI_Send(&u1[1][1][1],1,FB,nbrs[FRONT],3,MPI_COMM_WORLD);
MPI_Recv(&u1[1][1][c-1],1,FB,nbrs[BACK],3,MPI_COMM_WORLD, &status);
MPI_Send(&u1[1][1][c-2],1,FB,nbrs[BACK],4,MPI_COMM_WORLD);
MPI_Recv(&u1[1][1][0],1,FB,nbrs[FRONT],4,MPI_COMM_WORLD, &status);
MPI_Type_free (&FB);
MPI_Datatype LR;
MPI_Type_vector(b-2,c-2,c,MPI_FLOAT,&LR);
MPI_Type_commit(&LR);
MPI_Send(&u1[1][1][1],1,LR,nbrs[LEFT],5,MPI_COMM_WORLD);
MPI_Recv(&u1[a-1][1][1],1,LR,nbrs[RIGHT],5,MPI_COMM_WORLD, &status);
MPI_Send(&u1[a-2][1][1],1,LR,nbrs[RIGHT],6,MPI_COMM_WORLD);
MPI_Recv(&u1[0][1][1],1,LR,nbrs[LEFT],6,MPI_COMM_WORLD, &status);
MPI_Type_free (&LR);
for (i=0; i<a; i++) { for (j=0; j<b; j++) { for (k=0; k<c; k++) {
u0[i][j][k]=u1[i][j][k]; } } }
if (nbrs[FRONT]==-1)
{ for (i=1; i<a-1; i++) { for (j=1; j<b-1; j++) { u0[i][j][0]=0; u0[i][j][1]=0; } } }
if (nbrs[BACK]==-1)
{ for (i=1; i<a-1; i++) { for (j=1; j<b-1; j++) { u0[i][j][c-1]=0; u0[i][j][c-2]=0; } } }
if (nbrs[DOWN]==-1)
{ for (i=1; i<a-1; i++) { for (k=1; k<c-1; k++) { u0[i][b-1][k]=0; u0[i][b-2][k]=0; } } }
if (nbrs[UP]==-1)
{ for (i=1; i<a-1; i++) { for (k=1; k<c-1; k++) { u0[i][0][k]=0; u0[i][1][k]=0; } } }
if (nbrs[LEFT]==-1)
{ for (j=1; j<b-1; j++) { for (k=1; k<c-1; k++) { u0[0][j][k]=0; u0[1][j][k]=0; } } }
if (nbrs[RIGHT]==-1)
{ for (j=1; j<b-1; j++) { for (k=1; k<c-1; k++) { u0[a-1][j][k]=0; u0[a-2][j][k]=1; } } }
}
if (rank==0)
{ for (i=1; i<a-1; i++) { for (j=1; j<b-1; j++) { for (k=1; k<c-1; k++) {
x=float(coords[0])/float(dims[0])+(i-1)*h;
|
|
y=float(coords[1])/float(dims[1])+(b-2-j)*h;
z=float(coords[2])/float(dims[2])+(k-1)*h;
printf("u[%i][%i][%i] = %f\tx = %f\ty = %f\tz = %f\n",i,j,k,u0[i][j][k],x,y,z); } } } }
FILE *file;
int count=(a-2)*(b-2)*(c-2);
char s[count];
sprintf(s, "a%i.dat\0", rank);
file = fopen(s, "w+");
fprintf(file, "ZONE I=%i,J=%i,K=%i,F=POINT\n",a-2,b-2,c-2);
for(i=1;i<a-1;i++) { for(j=b-2;j>0;j--) { for (k=1; k<c-1; k++) {
x=float(coords[0])/float(dims[0])+(i-1)*h;
y=float(coords[1])/float(dims[1])+(b-2-j)*h;
z=float(coords[2])/float(dims[2])+(k-1)*h;
fprintf(file,"%f\t%f\t%f\t%f\n",x,y,z,u0[i][j][k]); } } }
fclose(file);
1. ?
, , . , . , . :
1) (CAD Computer Aided Design). . 2) . , ; 3) . , , .. , , . 4) . , , . 5) . . 6) -. , . , , , .
2. , MPI?
DOUBLE PRECISION MPI_WTIME
, . , .
:
int main (int argc, char **argv)
{
int rank, size, wtime;
double startwtime=0, endwtime; -
double s=0;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
startwtime=MPI_Wtime(); // wtime
printf ("hello world %d, size %d\n", rank, size);
endwtime=MPI_Wtime(); // wtime
printf ("time %d\n",(endwtime-startwtime)*size); //
MPI_Finalize();}