Автор работы: Пользователь скрыл имя, 17 Января 2014 в 17:38, курсовая работа
Завдання: Розробити схему та описати процедуру перемноження матриці А (розмірністю N1*N2) на матрицю В (розмірністю N2*N3) на структурі з восьми процесорів. Для цієї структури визначити час виконання алгоритму, відсоток послідовної частини алгоритму та ефективність алгоритму.
В даній курсовій роботі проведено розробку програмної реалізації восьми процесорної паралельної системи зі розподіленою пам’яттю, яка виконує множення двох матриць розмірами А(190*88) та В(88*149).
Додаток А
Текст програми на C++ з використанням бібліотеки МРІ:
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <iostream>
#include "mpi.h"
#include <Windows.h>
#include <conio.h>
using namespace std;
const int route=0;
const int circle[] = {0,4,6,1,3,7,2,5};
const int procNumber=8;
const int N1=190;
const int N2=88;
const int N3=149;
int procRank;
const int root=0;
MPI_Status Status;
struct A{
int row;
int n1;
int n2;
double arr[N1/8+N1][N2];
};
struct B{
int col;
int n2;
int n3;
double arr[N2][N3/8+N3];
};
struct R{
int n1;
int n3;
double arr[N1/8+N1][N3];
};
double matrixA[N1][N2]={0};
double matrixB[N2][N3]={0};
double Res[N1][N3]={0};
A subA[procNumber];
B subB[procNumber];
A procA;
B procB;
B procBtmp;
R procRes;
R result[procNumber];
int NextProc;
int PrevProc;
int procSize;
//Збір
void DataReplication(){
if(procRank==7||procRank==5||
MPI_Send(&procRes,sizeof(
if(procRank==1){
MPI_Recv(&procRes,sizeof(
MPI_Send(&procRes,sizeof(
}
if(procRank==7){
MPI_Recv(&procRes,sizeof(
MPI_Send(&procRes,sizeof(
}
if(procRank==5){
MPI_Recv(&procRes,sizeof(
MPI_Send(&procRes,sizeof(
}
}
if(procRank==2)MPI_Send(&
if(procRank==6)MPI_Send(&
if(procRank==3)MPI_Send(&
if(procRank==root){
result[root]=procRes;
MPI_Recv(&result[7],sizeof(
MPI_Recv(&result[5],sizeof(
MPI_Recv(&result[1],sizeof(
MPI_Recv(&result[4],sizeof(
MPI_Recv(&result[2],sizeof(
MPI_Recv(&result[6],sizeof(
MPI_Recv(&result[3],sizeof(
}
}
//початкова розсилка
void DataDistribution(){
if(procRank==root){
procA = subA[root];
procB = subB[root];
for(int i=0;i<procNumber;i++)
if(i!=root){
MPI_Send(&subA[circle[i]],size
MPI_Send(&subB[circle[i]],size
}
}
MPI_Status Status;
if(procRank!=root){
MPI_Recv(&procA,sizeof(procA),
MPI_Recv(&procB,sizeof(procB),
}
}
//пересилка підматриці і перемноження
void mull(){
for(int i=0;i<procA.n1;i++)
for(int j=0;j<procB.n3;j++)
for(int k=0;k<procA.n2;k++)
procRes.arr[i][j+procB.col]+=
}
void DataSend(){
procRes.n1=procA.n1;
procRes.n3=N3;
//mull();
for(int k=0;k<procNumber;k++){
for(int i=0;i<procNumber;i++){
if(procRank==circle[i]){
if( i % 2==0 ) {
MPI_Send(&procB,sizeof(B),MPI_
MPI_Recv(&procBtmp,sizeof(B),
procB=procBtmp;
} else {
MPI_Recv(&procBtmp,sizeof(B),
MPI_Send(&procB,sizeof(B),MPI_
procB=procBtmp;
}
}
}
mull();
}
}
void SetRank()
{
if(procRank==0)
{
NextProc = 4;
PrevProc = 5;
}
if(procRank==1)
{
NextProc = 3;
PrevProc = 6;
}
if(procRank==2)
{
NextProc = 5;
PrevProc = 7;
}
if(procRank==3)
{
NextProc = 7;
PrevProc = 1;
}
if(procRank==4)
{
NextProc = 6;
PrevProc = 0;
}
if(procRank==5)
{
NextProc = 0;
PrevProc = 2;
}
if(procRank==6)
{
NextProc = 1;
PrevProc = 4;
}
if(procRank==7)
{
NextProc = 2;
PrevProc = 3;
}
}
int main(int argc, char* argv[])
{
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD,&
MPI_Comm_size(MPI_COMM_WORLD,&
if(procSize!=8){
cout<<"Must be 8 process"<<endl;
MPI_Finalize();
return 1;
}
if(procRank==root){
//заповнення А
for(int i=0;i<N1;i++)
for(int j=0;j<N2;j++)
matrixA[i][j]=rand()%9+1;
cout<<"Matrix A"<<endl;
for(int i=0;i<N1;i++){
for(int j=0;j<N2;j++)
cout<<matrixA[i][j]<<" ";
cout<<endl;
}
//заповнення В
for(int i=0;i<N2;i++)
for(int j=0;j<N3;j++)
matrixB[i][j]=rand()%9+1;
cout<<endl<<"Matrix B"<<endl;
for(int i=0;i<N2;i++){
for(int j=0;j<N3;j++)
cout<<matrixB[i][j]<<" ";
cout<<endl;
}
//перемноження матриць
for(int i=0;i<N1;i++)
for(int j=0;j<N3;j++)
for(int k=0;k<N2;k++)
Res[i][j]+=matrixA[i][k]*
cout<<endl<<"Result"<<endl;
for(int i=0;i<N1;i++){
for(int j=0;j<N3;j++)
cout<<Res[i][j]<<" ";
cout<<endl;
}
//розбиття на підматриці
//А
int rowsSum=0;
int restRows = N1;
int restProc = procNumber;
for(int i=0;i<procNumber;i++)
{
subA[i].row=rowsSum;
subA[i].n1 = restRows/restProc;
subA[i].n2 = N2;
for (int k=0;k<subA[i].n1;k++)
for(int j=0;j<subA[i].n2;j++)
subA[i].arr[k][j] = matrixA[k+rowsSum][j];
rowsSum+=subA[i].n1;
restRows -= restRows/restProc;
restProc--;
}
//В
rowsSum=0;
restProc = procNumber;
restRows = N3;
for(int i=0;i<procNumber;i++)
{
subB[i].col = rowsSum;
subB[i].n2 = N2;
subB[i].n3 = restRows/restProc;
for (int k= 0;k<subB[i].n2;k++)
for(int j=0;j<subB[i].n3;j++)
subB[i].arr[k][j] = matrixB[k][j+rowsSum];
rowsSum+=subB[i].n3;
restRows -= restRows/restProc;
restProc--;
}
}
//cout<<"SetRank"<<endl;
SetRank();
//cout<<"DataDistribution()"<<
DataDistribution();
DataSend();
//cout<<"DataReplication()"<<
DataReplication();
if(procRank==root){
cout<<endl<<"Paralel rez"<<endl;
for(int k=0;k<procNumber;k++)
for(int i=0;i<result[k].n1;i++){
for(int j=0;j<result[k].n3;j++)
cout<<result[k].arr[i][j]<<" ";
cout<<endl;
}
}
MPI_Finalize();
return 0;
}
Информация о работе Паралельне виконання операцій множення матриць