這里我先對MPI進行一下簡單的介紹,MPI的全稱是Message Passing Interface,即消息傳遞接口。
-
它並不是一門語言,而是一個庫,我們可以用Fortran、C、C++結合MPI提供的接口來將串行的程序進行並行化處理,也可以認為Fortran+MPI或者C+MPI是一種再原來串行語言的基礎上擴展出來的並行語言。
-
它是一種標准而不是特定的實現,具體的可以有很多不同的實現,例如MPICH、OpenMPI等。
-
它是一種消息傳遞編程模型,顧名思義,它就是專門服務於進程間通信的。
MPI的工作方式很好理解,我們可以同時啟動一組進程,在同一個通信域中不同的進程都有不同的編號,程序員可以利用MPI提供的接口來給不同編號的進程分配不同的任務和幫助進程相互交流最終完成同一個任務。就好比包工頭給工人們編上了工號然后指定一個方案來給不同編號的工人分配任務並讓工人相互溝通完成任務。
1.首先MPI是基於消息傳遞的並行計算模式,與之前的pthread,openMP等共享內存的完全兩碼事,這是首先要明白的。
2.MPI程序中,既有串行執行的程序,也有並行執行的程序。其中,並行的部分全部放在MPI_Init(&argc,&argv)和MPI_Finalize()內部。(其實外部的程序也都會在每一個進程中運行,此處不太理解內部具體是怎么搞的)
3.也是最讓我開始納悶的地方:MPI 的程序怎么在代碼中控制開多少個進程啊?費了我半天勁,原來MPI有自己的編譯和運行命令。
最簡單的編譯命令 mpicc mpi.c -o mpi
最簡單的運行命令mpirun -np 4 ./mpi 其中-np就是指定開啟的進程數
4.貌似MPI發揮作用是要在集群上運行的,但是單機下也可以運行,用上述命令即可。
還有很多不懂正在學習
---------------------
一、mpi的安裝
去微軟下載安裝
直接下載地址(點擊下載)
1 點擊下面
2.直接點擊下載
3、直接運行msi文件,按照安裝提示安裝
4、安裝后會有3個文件夾
主要是頭文件include與庫文件lib
5、打開vs2017,創建一個空的.cpp文件
右擊上面的那個,調出菜單,找到最下面的“”屬性“”
打開是這樣子的
3、導入頭文件,庫文件
(1)頭文件
如果是64位選擇x86文件夾,32位選x64
(2)庫文件夾
導入方式和頭文件的一樣,不過應該注意的是選文件夾是一定要選x86或者是x64,否則可能會報找不到xxx.lib
(3)添加依賴項
點擊小勾,這個地方選中這行是會出現小勾
復制幾個xxx.lib的名字依次填進去中間用;隔開或者換行寫
最后點擊“”應用“”就行
二、mpi的簡單運用運用
(1)常用的基本函數
int MPI_Init(int* argc ,char** argv[] );//初始化 int MPI_Comm_size(MPI_Comm comm ,int* size);//進程數 int MPI_Comm_rank(MPI_Comm comm ,int* rank);//當前進程號 int MPI_Send(void *message, int count, MPI_Datatype datatype, int rank, int tag, MPI_Comm comm);//發送信息 int MPI_Recv(void *message, int count, MPI_Datatype datatype, int rank, int tag, MPI_Comm comm, MPI_Status *status);//接受信息 int MPI_Finalize(void);//釋放init的資源
(2)函數參數介紹
MPI_Comm comm 通信域,一組共享該空間的進程 int *size 進程數將會存在里面 int *rank 進程號將會存在里面,進程號為大於等於0的整數,其中主進程進程號(rank)為0 void *message 為被發送的信息 int count 你發送的消息的個數(注意:不是長度,例如你要發送一個int整數,這里就填寫1,如要是發 送“hello”字符串,這里就填寫6(C語言中字符串未有一個結束符,需要多一位))。 MPI_Datatype datatype 你要發送的數據類型,需要用MPI定義的數據類型 int dest 進程號 int tag 信息標簽(當發送的信息標簽和接受端的信息標簽相等時在,接受端才接受) MPI_Status *status 包含實際接收到的消息的有關信息
(3)簡單實例
#include<stdio.h> #include<string.h> #include<mpi.h> #pragma comment(lib,"msmpi.lib") int main(int argc, char* argv[]) { int proceNum;//進程數量 int thisId;//當前進程id MPI_Status status;//狀態信息 char message[1024];//發送信息內容 MPI_Init(&argc, &argv);//初始化mpi進程 MPI_Comm_rank(MPI_COMM_WORLD, &thisId);//獲取當前進程號 if (thisId == 0) { MPI_Comm_size(MPI_COMM_WORLD, &proceNum);//獲取進程數量 printf("當前共有%d個進程\n", proceNum); } if (thisId != 0) //當前進程不是主進程 { printf ("我是進程%d,正在發送......", thisId); sprintf(message, "你好主進程!!"); // int MPI_Send(void *message, int count, MPI_Datatype datatype, int rank, int tag, MPI_Comm comm);發送信息到0進程(主進程) MPI_Send(message, strlen(message)+1, MPI_CHAR, 0, 9527, MPI_COMM_WORLD); //MPI_COMM_WORLD:包含程序中所有MPI進程 } else {//thisId != 0即不是主進程,那么這里就是主進程 for (int i = 1; i < proceNum; i++)//其實這是阻塞式的發送和接受,所以可以靠循環來讀取message所指緩沖區的信息 { // int MPI_Recv(void *message, int count, MPI_Datatype datatype, int rank, int tag, MPI_Comm comm, MPI_Status *status);//接受信息 MPI_Recv(message, 1024, MPI_CHAR, i, 9527, MPI_COMM_WORLD, &status); printf("你好,進程%d\n", status.MPI_SOURCE); } } MPI_Finalize(); return 0; }
然后運行,如果在這里出現如下錯誤
error C4996: 'sprintf': This function or variable may be unsafe.
解決如下:
原因解釋
這種微軟的警告,主要因為那些C庫的函數,很多函數內部是不進行參數檢測的(包括越界類的),微軟擔心使用這些會造成內存異常,所以就改寫了同樣功能的函數,改寫了的函數進行了參數的檢測,使用這些新的函數會更安全和便捷。關於這些改寫的函數你不用專門去記憶,因為編譯器對於每個函數在給出警告時,都會告訴你相應的安全函數,查看警告信息就可以獲知,在使用時也再查看一下MSDN詳細了解。庫函數改寫例子:
mkdir改寫為 _mkdir
fopen”改寫為 fopen_s
stricmp改寫為 stricmp_s
sprintf改寫為sprintf_s
strcpy改寫為strcpy_s
方法一:調用VS2005鼓吹的那些帶“_s”后綴的非標准函數,即在其后加上"_S",如sprintf改為sprintf_s 。
方法二:在文件最開始添加#define _CRT_SECURE_NO_DEPRECATE或#pragma warning(disable:4996) ,這是忽略警告的方法(一般比較少用)。
方法三:干粹在工程屬性中設置(推薦)。
在工程屬性中設置的方法如下:
對於VC6:
打開Project----settings----Resources----Preprocessor definitions,
添加_CRT_SECURE_NO_DEPRECATE和_SCL_SECURE_NO_DEPRECATE這兩個宏。
對於VS系列的版本:
打開項目----項目屬性---配置屬性----C/C++ ----預處理器----預處理定義,
添加_CRT_SECURE_NO_DEPRECATE和_SCL_SECURE_NO_DEPRECATE這兩個宏。
成功運行之后:
然后右擊左上角藍色的mai.cpp打開所在文件夾

返回上一級

進入Debug文件夾
空白處shift+鼠標右鍵,打開菜單然后打開Powershell窗口,輸入mpiexec -n 17 mpi.exe
,17為進程數將會生成0-16的進程號。