MPICH2 Windows 多节点并行计算Demo

来源:互联网 发布:祝利荣关键k线指标源码 编辑:程序博客网 时间:2024/04/29 02:32

刚刚接触MPICH,入手写了一个计算A * B(A 矩阵,B 向量)的测试程序,以熟悉MPICH。

程序以主从模式进行设计,主节点负责分发计算任务到不同的计算节点,然后接收从计算节点发送来的计算结果。

应用OpenThread线程库,在主机端创建数据接收子线程,专门负责接收计算结果。程序代码如下:

数据接收子线程:

<span style="font-size:14px;">#pragma once#include <list>#include "OpenThreads/Thread"#include "OpenThreads/Mutex"#include "OpenThreads/ScopedLock"#include "mpi.h"/*数据接收线程*/class ReceiveThread :public OpenThreads::Thread{public:ReceiveThread(){isRuning = false;receiveFanish = false;}virtual ~ReceiveThread(void){}//接收线程开始运行void run(){isRuning = true;for (int i = 0;i < row_col;++i){MPI_Status status;std::cout<<"Master begin to receive result !!!!"<<std::endl;//接收计算节点发送来的计算结果MPI_Recv(result++,1,MPI_INTEGER,MPI_ANY_SOURCE,i,MPI_COMM_WORLD,&status);std::cout<<"0 receive from "<<status.MPI_SOURCE<<std::endl;{//获取idleList的使用权OpenThreads::ScopedLock<OpenThreads::Mutex> mutlock(idleMutex);//将发送结果的节点放到空闲节点列表idleList->push_back(status.MPI_SOURCE);std::cout<<"!!!RECEIEVE THREAD!!!"<<&idleList<<"Receive Thread  idleList size::"<<idleList->size()<<std::endl;}std::cout.flush();}//接收完毕receiveFanish = true;}void setIdleList(std::list<int> *_idleList){idleList = _idleList;}void setResult(int *_result){result = _result;}void setRowCol(int _rowCol){row_col = _rowCol;}bool getReceiveFanish(){return receiveFanish;}bool getIsRunning(){return isRuning;}OpenThreads::Mutex* getMutex(){return &idleMutex;}private:bool isRuning;std::list<int> *idleList;int *result;int row_col;bool receiveFanish;OpenThreads::Mutex idleMutex;};</span>
main函数

<span style="font-size:14px;">#include <iostream>#include <list>#include "OpenThreads/Thread"#include "OpenThreads/Mutex"#include "OpenThreads/ScopedLock"#include "mpi.h"#include "ReceiveThread.h"void initial(int _row_col,int _numNodes,int** &A,int *&B,std::list<int> &idleList){//初始化矩阵和向量for (int i = 0;i < _row_col;++i){A[i] = new int[_row_col];for (int j = 0;j < _row_col;++j){A[i][j] = 1;}B[i] = 10;}for (int i = 1;i<_numNodes;++i){idleList.push_back(i);}}void main(int argc,char *argv[]){//矩阵的行列数int row_col = 10;int numNodes,myRank;//空闲的节点列表std::list<int> idleList;//计算结果int *result = new int[row_col];MPI_Init(&argc,&argv);MPI_Comm_rank(MPI_COMM_WORLD,&myRank);MPI_Comm_size(MPI_COMM_WORLD,&numNodes);std::cout<<myRank<<" : start!!!!!!\n";if (myRank == 0){int ** A = new int*[row_col];int * B = new int[row_col];//初始化矩阵、向量、空闲节点列表initial(row_col,numNodes,A,B,idleList);ReceiveThread *receiveTh = new ReceiveThread();receiveTh->setIdleList(&idleList);receiveTh->setRowCol(row_col);receiveTh->setResult(result);//将B向量以广播的形式发送给各个节点MPI_Bcast(B,row_col,MPI_INTEGER,0,MPI_COMM_WORLD);for (int i = 0;i < row_col;++i){{//对空闲列表加锁,确保数据一致性OpenThreads::ScopedLock<OpenThreads::Mutex> mutlock(*receiveTh->getMutex());//没有空闲节点则等待if (!idleList.empty()){//从空闲列表中取一个节点int nodeId = idleList.front();idleList.pop_front();std::cout<<i<<" send message to "<<nodeId<<std::endl;//发送信息通知节点接收数据,并给出tagMPI_Send(&i,1,MPI_INTEGER,nodeId,nodeId,MPI_COMM_WORLD);//发送数据                                                                                                                                                MPI_Send(A[i],row_col,MPI_INTEGER,nodeId,i,MPI_COMM_WORLD);//开启接收线程,准备接收计算结果if (!receiveTh->getIsRunning()){receiveTh->startThread();}std::cout.flush();}else{--i;continue;}}}//判断计算结果是否接收完毕,未完成则等待while(!receiveTh->getReceiveFanish()){}//打印计算结果for (int i = 0;i < row_col;++i ){std::cout<<result[i]<<" ";std::cout<<std::endl;}}else{//矩阵的一行int *A = new int[row_col];//B向量int *B = new int[row_col];//接收向量BMPI_Bcast(B,row_col,MPI_INTEGER,0,MPI_COMM_WORLD);std::cout<<myRank<<":"<<B[1]<<std::endl;MPI_Status status;//接收数据的标示,也就是A矩阵的行号,由Master节点发送给计算节点int tag;bool continueRun = true;while(continueRun){//接收tagMPI_Recv(&tag,1,MPI_INTEGER,0,myRank,MPI_COMM_WORLD,&status);std::cout<<myRank<<"  :::  tag = "<<tag<<std::endl;//根据tag接收矩阵的一行MPI_Recv(A,row_col,MPI_INTEGER,0,tag,MPI_COMM_WORLD,&status);std::cout<<myRank<<" : : receive data from 0"<< A[1]<<std::endl;int sum = 0;for (int i = 0;i < row_col;++i){sum += A[i] * B[i];}std::cout<<myRank<<" ::: calculate fanished!!!"<<std::endl;//发送计算结果MPI_Send(&sum,1,MPI_INTEGER,0,tag,MPI_COMM_WORLD);std::cout<<myRank<<":: send result to master:::"<<sum<<std::endl;std::cout.flush();}}MPI_Finalize();}</span>



0 0
原创粉丝点击