如何解决如何使用C ++仅为Open / Microsoft MPI中的某些进程创建关键部分?
我是MPI的新手,想了解如何为仅几个正在运行的流程创建关键部分。我知道我可以为所有进程创建这样的文件:
for (int i = 0; i < 1000; ++i)
{
MPI_Barrier(MPI_COMM_WORLD);
std::cout << "RANK " << rank << " PRINTS " << i << std::endl;
}
但是,如果至少一个进程不会触发MPI_Barrier(),则此操作将不起作用。假设我是这样做的:
if(rank > 0)
for (int i = 0; i < 1000; ++i)
{
MPI_Barrier(MPI_COMM_WORLD);
std::cout << "RANK " << rank << " PRINTS " << i << std::endl;
}
这将崩溃,因为第0个进程将跳过循环。那么,如何允许所有其他进程同步打印,并在第0个进程中做其他事情(假设所有打印结束后都等待消息)?
解决方法
正如 @Gilles Gouaillardet 所指出的那样,您可以使用MPI_Comm_split
创建不具有等级0的通信器。可以使用此新通信器调用MPI_Barrier
来同步其余过程。等级0完成后,可以调用COMM_WORLD
上的barrier并等待其余进程对其进行调用。
其余进程(例如1到N)可以通过使用for loop
到1
上的N
迭代和{ {1}}块,它基于if
和rank
执行代码区域,如下面的示例所示。
MPI_Barrier
另一种方法(无需创建新的通信器)是您可以使用环发消息(环广播)的概念。
MPI_Comm_split(MPI_COMM_WORLD,color,key,newcomm) // create new comm without rank 0
if(rank>0) {
for (int i = 1; i < size; ++i)
{
if(rank == i) { // Critical region. Only one rank can enter here at a time. Here it enters sequentially from 0 to size
std::cout << "RANK " << rank << " PRINTS " << i << std::endl; // After calling Critical Session Part,call barrier to signal other processes.
MPI_Barrier(newcomm);
} else {
MPI_Barrier(newcomm); // all other proesses (except rank == i) should wait and do not enter the critical region
}
}
MPI_Barrier(MPI_COMM_WORLD);// This barrier will be called with rank 0
} else {
//do some work for rank 0
// wait for the rest of the processes
MPI_Barrier(MPI_COMM_WORLD);
}
在这里,if (rank == 0) {
value = 1;
MPI_Send( &value,1,MPI_INT,rank + 1,MPI_COMM_WORLD );
// Do something useful
}
else {
MPI_Recv( &value,rank - 1,MPI_COMM_WORLD,&status );
if (rank < size - 1){
//criticalregion
MPI_Send( &value,MPI_COMM_WORLD );
}
}
MPI_Barrier(MPI_COMM_WORLD);
向rank 0
发送消息,而消息又向rank 1
发送,依此类推。这样,进程在接收到消息后可以依次执行代码(关键区域),然后将消息发送到更高级别并触发执行。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。