MPI_Send(comp,size,MPI_INT,1,tag,ring);
};
};
if(rank){
MPI_Recv(&dim,1,MPI_INT,sour,tag,ring,&st);
MPI_Recv(comp,size,MPI_INT,sour,tag,ring,&st);
if(rank<(size-1)){
MPI_Send(&dim,1,MPI_INT,dest,tag,ring);
MPI_Send(comp,size,MPI_INT,dest,tag,ring);
};
};
for(i=0;i<=size-1,comp[i]>0;i++);
size=i<size?i:size;
if(!comp[rank])exit(0);
/* Memory allocation */
A=(float *)malloc(sizeof(float)*(dim+1)*comp[rank]);
res=(float *)malloc(sizeof(float)*dim);
B=(float *)malloc((dim+1)*sizeof(float));
if(!A||!res||!B){printf("Can't allocate memory...\n");return 1;};
if(!rank){/*Processor with rank=0 initialise*/
counter=0;
for(i=1;i<=dim;i++){/*For each row of the whole matrix...*/
if((i-1)%size==0)/*Own string*/{
for(j=1;j<=dim+1;j++)fscanf(inp,"%f",A+counter*(dim+1)+j-1);
counter++;
}else{
for(j=1;j<=dim+1;j++)fscanf(inp,"%f",B+j-1);
MPI_Send(B,dim+1,MPI_FLOAT,(i-1)%size,tag,ring);
};
};
if(fclose(inp))printf("Error closing file...\n");
time(tp1);
};
if(rank){
/*Now we'll recieve matrix*/
for(i=1;i<=comp[rank];i++){
MPI_Recv(A+(i-1)*(dim+1),dim+1,MPI_FLOAT,0,tag,ring,&st);
};
};
/*Matrix transforming*/
for(i=1;i<=comp[rank];i++){
for(j=1;j<(rank+1+size*(i-1));j++){
if(((j-1)%size)==rank){
if(A[(i-1)*(dim+1)+j-1]){
localnum=(j-1)/size+1;
c=-A[(i-1)*(dim+1)+j-1]/A[(localnum-1)*(dim+1)+j-1];
for(j1=j;j1<=dim+1;j1++)A[(i-1)*(dim+1)+j1-1]+=c*A[(localnum-1)*(dim+1)+j1-1];
};
}else if(j>(rank+1+size*(i-2))){
MPI_Recv(B,dim+1,MPI_FLOAT,(j-1)%size,tag,ring,&st);
for(k=i;k<=comp[rank];k++)if(A[(k-1)*(dim+1)+j-1]){
c=-A[(k-1)*(dim+1)+j-1]/B[j-1];
for(j1=j;j1<=dim+1;j1++)A[(k-1)*(dim+1)+j1-1]+=c*B[j1-1];
};
};
};
for(j=rank+1+size*(i-1)+1,compID=rank+1;(j<=dim)&&(compID<=rank+size-1);j++,compID++){
MPI_Send(A+(dim+1)*(i-1),dim+1,MPI_FLOAT,compID%size,sendtag,ring);
}
for(j=i+1;j<=comp[rank];j++)if(A[(j-1)*(dim+1)+rank+size*(i-1)]){
c=-A[(j-1)*(dim+1)+rank+size*(i-1)]/A[(i-1)*(dim+1)+rank+size*(i-1)];
for(j1=rank+size*(i-1)+1;j1<=dim+1;j1++)A[(j-1)*(dim+1)+j1-1]+=c*A[(i-1)*(dim+1)+j1-1];
};
};
/*Result calculating*/
for(i=comp[rank];i>=1;i--){
if((rank+1+(i-1)*size)==dim){
}else MPI_Recv(res,dim,MPI_FLOAT,dest,tag,ring,&st);
res[rank+1+(i-1)*size-1]=A[i*(dim+1)-1];
for(j=rank+1+(i-1)*size+1;j<=dim;j++)res[rank+1+(i-1)*size-1]-=res[j-1]*A[(i-1)*(dim+1)+j-1];
if(!A[(i-1)*(dim+1)+rank+(i-1)*size]){
printf("Matrix is null determined...\n");
MPI_Finalize();
exit(0);
};
res[rank+1+(i-1)*size-1]/=A[(i-1)*(dim+1)+rank+(i-1)*size];
if((rank+1+(i-1)*size)!=1){
MPI_Send(res,dim,MPI_FLOAT,sour,tag,ring);
};
};
if(!rank){
time(tp2);
time_=difftime(*tp2,*tp1);
printf("time=%f",time_);
if(!(outp=fopen("./output.txt","w"))){
printf("Couldn't open output file...\n");
exit(1);
};
fprintf(outp,"Result:\n");
for(i=1;i<=dim;i++)fprintf(outp,"%f ",res[i-1]);
fprintf(outp,"\nExecution time: %f\n",time_);
};
if(A)free(A);
if(B)free(B);
if(comp)free(comp);
if(res)free(res);
MPI_Finalize();
return 0;
};
Для тестирования на больших матрицах была написана программа, генерирующая СЛАУ с единичной матрицей, единичным вектором правых частей и, очевидно, единичным решением.
Расчёт на однопроцессорном компьютере (10 виртуальных процессоров)
Программа 1:
Размерность матрицы |
Время счёта |
100 |
9 |
500 |
50 |
Программа 2:
Размерность матрицы |
Время счёта |
100 |
11 |
500 |
55 |
Программа 1:
Размерность матрицы |
Время счёта |
Программа 2:
Размерность матрицы |
Время счёта |
Из результатов на однопроцессорной машине следует, что во втором методе больше времени, чем в первом тратится на пересылку данных, а именно, время во втором методе больше примерно на 10%.
Очевидно, что на одном компьютере никакого выигрыша от второго метода быть не должно, его и нет, он работает дольше только за счёт большего числа пересылок данных между процессорами.
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.