=================================版权声明=================================

版权声明:原创文章 禁止转载 

请通过右侧公告中的“联系邮箱(wlsandwho@foxmail.com)”联系我

勿用于学术性引用。

勿用于商业出版、商业印刷、商业引用以及其他商业用途。                   

 

本文不定期修正完善。

本文链接:http://www.cnblogs.com/wlsandwho/p/5931563.html

耻辱墙:http://www.cnblogs.com/wlsandwho/p/4206472.html

=======================================================================

最近在看《并行程序设计导论》([美] 帕切克 著;邓倩妮 等 译),然而这个是基于linux写的,本人专注Windows开发。

所以只能一边看一遍对应着写写代码了。

=======================================================================

既然在Windows上写,当然是用MS的东西啦。

这个是微软官网上的东西https://msdn.microsoft.com/en-us/library/bb524831%28v=vs.85%29.aspx

都是英文的:)。

本来想可能需要自己研究怎么搭环境,幸好MSDN上有篇文章详细的讲解了

https://blogs.technet.microsoft.com/windowshpc/2015/02/02/how-to-compile-and-run-a-simple-ms-mpi-program/

先截个图。

=======================================================================

由于本人用惯了Win7和VS2010,在家里的用的虚拟机,而这个文档至少是VS2012的教程,所以光看的话可能有出入,还是要照着做一番的。

=======================================================================

1 安装msmpisdk.msi和MSMpiSetup.exe,都是一路Next即可。下面是我的截图。

(这里两个包包都要安装,不然不会有官网里的那个截图。)

2 新建一个命令行程序,然后配置一下头文件和库文件的引用。

这个是头文件:

 这个是库文件:

3 写一个测试代码,国际惯例,HellWorld。

 1 // MPIHelloWorld.cpp : 定义控制台应用程序的入口点。
 2 // 王林森 20161005
 3 
 4 #include "stdafx.h"
 5 #include <iostream>
 6 #include <string>
 7 #include <sstream>
 8 
 9 #include <Windows.h> //为了能够使用Sleep
10 
11 #include "mpi.h"
12 #pragma comment(lib,"msmpi.lib")
13 
14 const int MAX_STRING=100;
15 
16 
17 int main()
18 {
19     int comm_size;
20     int comm_rank;
21 
22     MPI_Init(NULL,NULL);
23 
24     MPI_Comm_size(MPI_COMM_WORLD,&comm_size);
25     MPI_Comm_rank(MPI_COMM_WORLD,&comm_rank);
26 
27     std::string strGreeting;
28     std::string strRank;
29     std::string strSize;
30     std::stringstream ss;
31 
32     if (comm_rank!=0)
33     {
34         ss.clear();
35         ss<<comm_rank;
36         ss>>strRank;
37         ss.clear();
38         ss<<comm_size;
39         ss>>strSize;
40 
41         strGreeting="Greeting from process "+strRank+" of "+strSize+".";
42 
43         MPI_Send(strGreeting.c_str(),strGreeting.size(),MPI_CHAR,0,0,MPI_COMM_WORLD);
44 
45         std::cout<<"I'm slave "<<comm_rank<<"."<<std::endl;
46     }
47     else
48     {
49         std::cout<<"I'm master "<<comm_rank<<"."<<"I have received some messages:"<<std::endl;
50 
51         char greeting[MAX_STRING];
52 
53         for (int i=1;i<comm_size;i++)
54         {
55             memset(greeting,0,MAX_STRING);
56             
57             MPI_Recv(greeting,MAX_STRING,MPI_CHAR,i,0,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
58 
59             std::cout<<greeting<<std::endl;
60         }
61     }
62 
63     MPI_Finalize();
64 
65     Sleep(10000);//方便单进程时暂留10秒,看结果。
66 
67     return 0;
68 }

编译链接,OK。

4 运行。

直接使用F7是只能启动一个程序的,相当于这一组只有1个。如图:

使用mpiexec运行

=======================================================================

20170318 22:23 补充

 

 

=======================================================================

这是个SPMD程序。(SPMD,Single Program,Multiple Data,单程序多数据流)

=======================================================================

看这句:

1 MPI_Recv(greeting,MAX_STRING,MPI_CHAR,i,0,MPI_COMM_WORLD,MPI_STATUS_IGNORE);

当把i换成MPI _ANY_SOURCE时,会按照数据真实到达的顺序接收(而不是上述例子中的i的自增顺序)。

当把0换成MPI _ANY_TAG时,会接收所有tag的数据(而不仅仅是上述例子中的tag为0的数据)。

只有接收者可以使用通配符参数。

=======================================================================

就酱啦。