在前面的文章中,对点对点通信API进行了介绍,本文将对MPI组通信相关API进行介绍
一对多
Broadcast
将一个进程的数据广播到所有其他进程中,函数原型:
int MPI_Bcast(void *buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm);
函数参数详解:
- void *buffer:指向待广播的数据的起始地址。
- int count:待广播数据的数量。
- MPI_Datatype datatype:待广播数据的类型。
- int root:广播数据的根进程号。
- MPI_Comm comm:通信域。
使用时,需要指定进行分发数据的根进程号root,该进程的缓冲区中数据将会被复制到所有的当前通信域中的其他进程的缓冲区。
MPI_Bcast
本质上是点对点通信,只不过是一个进程重复的向其他不同进程发送数据的过程。
代码示例:
#include <mpi.h>
#include <stdio.h>
int main(int argc, char** argv) {
int rank, size, root = 0;
int data[4] = {
1, 2, 3, 4};
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
if (rank == root) {
// 广播数据
MPI_Bcast(data, 4, MPI_INT, root, MPI_COMM_WORLD);
} else {
// 接收广播数据
MPI_Bcast(data, 4, MPI_INT, root, MPI_COMM_WORLD);
}
// 输出每个进程接收到的数据
printf("Process %d received data: %d %d %d %d\n", rank, data[0], data[1], data[2], data[3]);
MPI_Finalize();
return 0;
}
Scatter
将一个进程的数据分割成等量的部分,并将每个部分发送给多个其他进程,每个接收进程接收到完整数据的一部分等量的数据,函数原型:
int MPI_Scatter(void *sendbuf, int sendcount,
MPI_Datatype sendtype, void *recvbuf, int recvcount,
MPI_Datatype recvtype, int root, MPI_Comm comm);
函数参数含义:
- void *sendbuf:指向待分发数据的起始地址。
- int sendcount:每个分发数据缓冲区的大小。
- MPI_Datatype sendtype:待分发数据缓冲区中数据的数据类型。
- void *recvbuf:指向接收分发数据的缓冲区。
- int recvcount:每个接收分发数据缓冲区的大小。
- MPI_Datatype recvtype:接收分发数据缓冲区中数据的数据类型。
- int root:分发数据的根进程号。
- MPI_Comm comm:通信域。
同样的,MPI_Scatter 函数需要指定分发操作的根进程号 root,该进程的缓冲区中的数据将被分发到所有其他进程的缓冲区中。
代码示例:
#include <mpi.h>
#include <stdio.h>
int main(int argc, char** argv) {
int rank, size;
int data[8] = {
1, 2, 3, 4, 5, 6, 7, 8};
int subdata[2];
MPI_Init(NULL, NULL);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
if (size != 4) {
fprintf(stderr, "Number of processes must be 4 for this example\n");
MPI_Abort(MPI_COMM_WORLD, 1);
}
MPI_Scatter(data, 2, MPI_INT, subdata, 2, MPI_INT, 0, MPI_COMM_WORLD);
// 输出每个进程接收到的数据
printf("Process %d received data: %d %d\n"