MPI中的临界区是什么?

12

我有一些代码可以将2D数组打印到标准输出。问题在于运行时,每个进程都会写入输出并且数据会重叠,使其无法使用。

如何在MPI中构建关键部分,以便只有一个进程进入我显示输出的部分?

我正在使用OpenMPI。

2个回答

21

使用 MPI_Barriers 进行分离。

rank = 0;
while (rank < total_processes) {
   if (myrank == rank) {
       printf ("Array printed by rank: %d\n", myrank);
       print_array();
       fflush (stdout);
   }
   rank ++;
   MPI_Barrier ();
}

1
你可能想在那里增加rank的值。 :) - suszterpatt
谢谢回复!这有一点好转,但还是有重叠 :( - alexsardan
1
嗯,看起来它似乎没有正确地刷新。也许你应该尝试写入不同的文件。每个等级可以写入output_$rank.txt或类似的文件。 - jman
是的,那最终是我的解决方案。我将输出到几个文件中。非常感谢! - alexsardan
我有一个类似的问题,只不过我正在尝试写入sqlite数据库。除了上面的答案之外,有没有更有效的方法?我想让每个进程按照它们发生的顺序执行。 - Harrison

1
#include<iostream>
#include"mpi.h"

void main(int args, char **argv) {
int i;
int nitems = 5 ;
int totalnodes, mynode;
double *array;
int trap_key = 0;
MPI_Status status;

MPI_Init(&args, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &totalnodes);
MPI_Comm_rank(MPI_COMM_WORLD, &mynode);

array = new double[nitems];

for (i = 0; i < nitems; i++)
    array[i] = double(i);

if (mynode != trap_key)  //this will allow only process 0 to skip this stmt
    MPI_Recv(&trap_key, 1, MPI_INT, mynode - 1, 0, MPI_COMM_WORLD, &status);

//here is the critical section 
cout << "I am Process: " << mynode << endl;
for (i = 0; i < nitems; i++) 
    cout << "array[" << i << "] =" << array[i] << endl;

if(mynode != totalnodes - 1)  // this will allow only the last process to
                              //skip this
    MPI_Send(&trap_key, 1, MPI_INT, mynode + 1, 0, MPI_COMM_WORLD);

MPI_Finalize(); 

}

请编译此代码,然后在调试文件目录中打开cmd,输入:mpiexec yourprojectname.exe

简单来说,我所做的就是用接收和发送操作将关键部分包围起来,这样每个进程都会等待前一个进程完成。


MPI_send() 和 MPI_recv() 是阻塞式点对点通信函数,因此当一个进程调用 MPI_recv() 函数时,它会进入忙等待状态直到接收到消息;同样的情况也适用于 MPI_send() 函数,它会等待消息被传递到目标进程。 - abdoo ayman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接