矩阵乘法 mpi c语言,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库  加载依赖项

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

int temp;

int **P = NULL;

P = (int**)malloc(sizeof(int)*am);

for (int i = 0; i < am; i++) {

P[i] = (int*)malloc(sizeof(int)*am);

}

for (int z = 0; z < am; z++) {

for (int i = 0; i < am; i++) {

P[z][i] = 0;

temp = 0;

for (int j = 0; j < am; j++) {

temp = +M[j*am + i] * N[z][j];

}

P[z][i] = temp;

}

}

cout << endl;

cout << "得到的矩阵为" << endl;

for (int i = 0; i < am; i++) {

for (int j = 0; j < am; j++) {

printf("%-8d", P[i][j]);

}

cout << endl;

}

end = MPI_Wtime();

double time = end - start2;

cout << "单进程需要的时间为" << end - start2 << endl;

}

else

{

/*

向各个进程发送信息

*/

for (int i = 0; i < am; i++) {

for (int j = 0; j < am; j++) {

buffer3[j] = N[j][i];

}

MPI_Send(buffer3, am, MPI_INT, i + 1, 11,MPI_COMM_WORLD);

}

for (int i = 0; i < am; i++) {

MPI_Send(&M[0 + 0], am*am, MPI_INT, i + 1, 22, MPI_COMM_WORLD);

}

free(N);

free(buffer3);

/*

回收各个进程的值

*/

int **P = NULL;

P = (int**)malloc(sizeof(int)*am);

for (int i = 0; i < am; i++) {

P[i] = (int*)malloc(sizeof(int)*am);

}

for (int i = 0; i < am; i++) {

MPI_Recv(&(P[i][0]), am, MPI_INT, i + 1, i + 1, MPI_COMM_WORLD, &status);

}

cout << endl;

cout << "得到的矩阵为" << endl;

for (int i = 0; i < am; i++) {

for (int j = 0; j < am; j++) {

//cout << P[i][j] << " ";

printf("%-8d", P[i][j]);

}

cout << endl;

}

end = MPI_Wtime();

double time = end - start2;

cout << "多进程需要的时间为" << end - start2 << endl;

}

}

``

其他进程则负责接收以及计算在发送给0进程

//接受来自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, amam, 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[jam + 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;

}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值