MPI实现矩阵相乘

之前一直想写一个关于MPI的例子,之后便想起了矩阵相乘,之后便在网上找资料,结果发现有些地方实现不了,于是便自己参考网上例子,踩了各种各样的雷之后于是才有了这次分享
1.MPI并行运算的思想
MPI并行运算通过由用户指定分配进程,来实现多进程的一种思想。MPI(Message-Passing-Interface 消息传递接口)实现并行是进程级别的,通过通信在进程之间进行消息传递。MPI并不是一种新的开发语言,它是一个定义可以被C、C++和Fortran程序调用的函数库。这些函数库里面主要涉及的是两个进程之间通信的函数。MPI可以在Windows和linux环境中都有相应的库,本篇以Windows10作为演示开发环境。
2.配置MPI环境
Windows为了兼容MPI,自己做了一套基于一般个人电脑的MPI实现。如果要安装正真意义上的MPI的话,请直接去www.mpich.org下载,里面根据对应的系统下载相应的版本。
安装 mpi
我的电脑是64位的,所以安装的是 mpi_x64.msi ,默认安在C:\Program Files\Microsoft HPC Pack 2008 R2,在此,为了之后调试代码方便,最好设置一下环境变量:在用户变量PATH中,加入:C:\Program Files\Microsoft HPC Pack 2008 R2\Bin\。

配置mpi
配置目录,即加载Include和Lib库
​​​​MPI实现矩阵相乘_第1张图片
加载依赖项
MPI实现矩阵相乘_第2张图片

3.编译
根据编程员的习俗先从一个helloworld开始

#include "mpi.h"  
#include   

int main(int argc, char* argv[])
{
    int rank, numproces;
    int namelen;
    char processor_name[MPI_MAX_PROCESSOR_NAME];

    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);//获得进程号
    MPI_Comm_size(MPI_COMM_WORLD, &numproces);//返回通信子的进程数

    MPI_Get_processor_name(processor_name, &namelen);
    fprintf(stderr, "hello world! process %d of %d on %s\n", rank, numproces, processor_name);
    MPI_Finalize();

    return 0;
}

4.mpi 矩阵相乘
接下来便开始我们的主题
实际的思想是使用0进程将矩阵切分成n份分别发送个其他的进程,再有其他的进程计算完成之后再发回0进程。

0进程进行分发,切分,以及整合矩阵。

if (myid == 0) {
  int  **N = NULL;
  int *buffer3 = nullptr;
  cout << "输入你的值" << endl;
  cin >> am;
  start2 = MPI_Wtime();
//将am的值广播给每一个进程(除了0进程)
  for (int i = 0; i < size; i++) {
   MPI_Send(&am, 1, MPI_INT, i + 1, 33, MPI_COMM_WORLD);
  }
  /*
  新建矩阵并初始化
  */
  srand((unsigned)time(NULL));
  buffer3 = (int*)malloc(sizeof(int)*am);
  int* M = new int[am*am];
  cout << "-------A类矩形------" << endl;
  for (int i = 0; i < am; i++) {
   for (int j = 0; j < am; j++) {
   M[i*am + j] = (rand() % 9) + 1;
    cout << M[i*am + j] << " ";
   }
   cout << endl;
  }
  N = (int**)malloc(sizeof(int)*am);
  for (int i = 0; i < am; i++) {
   N[i] = (int*)malloc(sizeof(int)*am);
   }
   cout << "-------B类矩形------" << endl;
  for (int i = 0; i < am; i++) {
   for (int j = 0; j < am; j++) {
   N[i][j] = (rand() % 9) + 1;
    cout << N[i][j] << " ";
   }
   cout << endl;
  }
 /*
   判断是否采用单线程
   */  
   if (numprocs 

//接受来自0进程的值
if (myid != 0) {
MPI_Recv(&am, 1, MPI_INT, 0, 33, MPI_COMM_WORLD, &status);
}
if (myid != 0 && myid <= am && numprocs>am) {
int temp;
int buffer2, m;
int buffer = new int[amam];
buffer2 = (int
)malloc(sizeof(int)am);
m = (int
)malloc(sizeof(int)am);
/

接受来自0进程的数据
/
MPI_Recv(buffer2, am, MPI_INT, 0, 11, MPI_COMM_WORLD, &status);
MPI_Recv(buffer, am
am, MPI_INT, 0, 22, MPI_COMM_WORLD, &status);
for (int i = 0; i < am; i++) {
m[i] = 0;
temp = 0;
for (int j = 0; j < am; j++) {
temp = +buffer[j
am + i] * buffer2[j];
}
m[i] = temp;
}
/*
将得到的数据进行计算并且将其传回0进程
*/
MPI_Send(m, am, MPI_INT, 0, myid, MPI_COMM_WORLD);
free(buffer);
free(buffer2);
free(m);
}
在这里我也将头部添上

#include
#include
#include
#include"mpi.h"
#include 
#include 
#pragma comment(lib,"msmpi.lib")
using namespace std;
int am;
int main(int argc, char **argv) {
 int numprocs;
 int myid, size;
 MPI_Status status;
 double start1, start2, end;
 MPI_Init(&argc, &argv);//MPI Initialize
 MPI_Comm_rank(MPI_COMM_WORLD, &myid);//获得当前进程号
 MPI_Comm_size(MPI_COMM_WORLD, &numprocs);//获得进程个数
 size = numprocs - 1;

尾部添上

MPI_Finalize();
 return 0;
}

你可能感兴趣的:(MPI实现矩阵相乘)