使用MPI实现broadcast、scatter、gather操作
1.MPI_Bcast:广播消息
MPI_Bcast用于将一个进程的buffer中的数据广播到其他进程的相同buffer变量中。
#include "stdio.h"
#include "mpi.h"
#include "stdlib.h"
#define N 10
int main(int argc, char** argv)
{int rank, data[10];MPI_Init(0, 0);MPI_Comm_rank(MPI_COMM_WORLD, &rank);if (rank == 0){for (int i = 0; i < 10; ++i){data[i] = i + 1;}}//进程0广播数据给所有进程MPI_Bcast(&data, 10, MPI_INT, 0, MPI_COMM_WORLD);//printf("process %d send data\n", rank);//每个进程该变量都被置为一样的值printf("process %d receive data:", rank);for (int i = 0; i < 10; ++i){printf("%d ", data[i]);}MPI_Finalize();return 0;
}
运行VS中的代码:
右击
复制完整路径
删除\Project1.sln点击回车
打开X64–>Debug
在路径处输入cmd
在命令窗口输入 -n 是端口数量 Project1.exe为路径下的exe文件
mpiexec -n 4 Project1.exe
2. MPI_Gather:收集消息
MPI_Gather用于将所有进程的某个变量值发送给某一个进程,并按照进程rank值排序。
可以看到各进程的data都发送到进程0,并在收集数据buf中按照进程rank排序,其他进程收集数据buf是随机值。
#include "stdio.h"
#include "mpi.h"
#include "stdlib.h"
#define N 10
int main(int argc, char** argv)
{int rank, data = 0;int size;MPI_Init(0, 0);MPI_Comm_size(MPI_COMM_WORLD, &size);MPI_Comm_rank(MPI_COMM_WORLD, &rank);//每个进程分别对data赋不同的值for (int i = 0; i < size; ++i){if (i == rank){data = i + 1;}}int receiveRank = 0; //收集消息的进程rankint* rbuf = new int[size];//进程0收集其他所有进程的数据MPI_Gather(&data, 1, MPI_INT, rbuf, 1, MPI_INT, receiveRank, MPI_COMM_WORLD);//只有进程0的数据是收集所有进程的值 其他进程全是随机值printf("process %d receive data:", rank);for (int i = 0; i < size; ++i){printf("%d ", rbuf[i]);}MPI_Finalize();return 0;
}
3. MPI_Scatter:散播消息
MPI_Scatter用于将某个进程的数据分配/散播给所有进程,发送的部分数据按照进程rank值依次发送给各进程
#include "stdio.h"
#include "mpi.h"
#include "stdlib.h"
#define N 10
int main(int argc, char** argv)
{int rank, data;int* sendBuf;int size;MPI_Init(0, 0);MPI_Comm_size(MPI_COMM_WORLD, &size);MPI_Comm_rank(MPI_COMM_WORLD, &rank);sendBuf = new int[size];for (int i = 0; i < size; ++i){sendBuf[i] = i + 1;}//发送消息的进程rankint sendRank = 0;//进程0散播(分配)数据到各进程MPI_Scatter(sendBuf, 1, MPI_INT, &data, 1, MPI_INT, sendRank, MPI_COMM_WORLD);//每个进程的data按照rank顺序依次被散播为不同数据printf("process %d receive data %d", rank, data);MPI_Finalize();return 0;
}