在之前的文章中,简单的写了一个非阻塞的通信代码介绍最最基本的使用:
int main(int argc, char *argv[])
{
int err = MPI_Init(&argc,&argv);
int rank,size;
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
int data = 100;
MPI_Request request;
MPI_Status status;
if(rank > 0)
{
MPI_Irecv(&data,1,MPI_INT,rank-1,0,MPI_COMM_WORLD,&request);
std::cout << "rank = " << rank << " recived data is : " << data << std::endl;
MPI_Wait(&request, &status);
std::cout << "rank = " << rank << " recived data is : " << data << std::endl;
}
if(rank < size - 1)
{
data = rank;
MPI_Isend(&data,1,MPI_INT, (rank + 1)%size, 0 ,MPI_COMM_WORLD, &request);
MPI_Wait(&request, &status);
}
err = MPI_Finalize();
return 0;
}
int MPI_Waitany(int count, MPI_Request array_of_requests[], int *indx, MPI_Status *status)
该函数等待由 count
个 MPI 请求组成的数组中的任一请求完成,返回值为完成操作的请求在数组中的索引值,将该值存储在 indx
指向的内存位置中。该函数会修改存储在与该请求相关联的通信状态对象(即 MPI_Status
)中的状态信息,这些信息可以通过 status
参数进行访问。
int MPI_Waitall(int count, MPI_Request array_of_requests[], MPI_Status array_of_statuses[])
该函数等待由 count
个 MPI 请求组成的数组中所有请求完成,返回值为 MPI_SUCCESS
。该函数会修改存储在与每个请求相关联的通信状态对象(即 MPI_Status
)中的状态信息,这些信息可以通过 array_of_statuses
参数进行访问。
int MPI_Waitsome(int incount, MPI_Request array_of_requests[], int *outcount,
int array_of_indices[], MPI_Status array_of_statuses[])
需要注意的是,这些串行通信操作函数都是阻塞式的,即在等待通信操作完成时,调用进程会一直阻塞直到所有通信操作完成并返回相应信息,因而开发者需要慎重使用这些函数,防止出现死锁等问题。
MPI_Testany、MPI_Testall ,MPI_Testsome 等函数是 MPI 中提供的非阻塞式通信操作函数,可以异步地对通信请求进行管理。MPI_Testany、MPI_Testall 等函数在等待通信请求完成时,不会阻塞调用进程,而是会立即返回。这种异步性能够最大限度地发挥程序的并行效率,尽量避免和其它通信请求的阻塞状态形成连锁反应,从而避免程序出现死锁问题。
int MPI_Testany(int count, MPI_Request array_of_requests[], int *indx, int *flag, MPI_Status *status)
该函数检查由 count
个 MPI 请求组成的数组中的任一请求是否已经完成,如果有已完成请求,则返回其在数组中的索引值,并将该值存储在 indx
指向的内存位置中。如果数组中的所有请求都没有完成,则返回值 flag
为 0。如果有任意一个请求已经完成,则返回值 flag
为 1。该函数会修改与请求相关联的通信状态对象(即 MPI_Status
)中的状态信息,这些信息可以通过 status
参数进行访问。
int MPI_Testall(int count, MPI_Request array_of_requests[], int *flag, MPI_Status array_of_statuses[])
该函数检查由 count
个 MPI 请求组成的数组中的所有请求是否都已经完成,如果所有请求都已经完成,则返回值 flag
为 1。否则,返回值 flag
为 0。该函数会修改与每个请求相关联的通信状态对象(即 MPI_Status
)中的状态信息,这些信息可以通过 array_of_statuses
参数进行访问。
int MPI_Testsome(int incount, MPI_Request array_of_requests[], int *outcount,
int array_of_indices[], MPI_Status array_of_statuses[])
该函数检查由 incount
个 MPI 请求组成的数组中的任一组请求是否已经完成,如果有已完成请求,则返回已完成操作的数量,并将这些完成操作的索引值存储在 array_of_indices
数组中。对应的通信状态对象则存储在数组 array_of_statuses
中,并返回值 MPI_SUCCESS
。如果没有请求已经完成,则返回值 outcount
为 0,函数也将返回值 MPI_SUCCESS
.