MPI:变量不会增加

时间:2012-12-19 21:42:37

标签: c mpi

我试图弄清楚MPI是如何工作的。因此,我从一个小例子开始:

...
MPI_Comm_rank(MPI_COMM_WORLD, &tid);
MPI_Comm_size(MPI_COMM_WORLD, &nthreads);

int message = 2;

if(tid != 0)
{
    MPI_Recv(&rec, 1, MPI_INT, tid-1, 0, MPI_COMM_WORLD, &status);
    printf("Process %i receive %i\n", tid, rec);
}

if(tid != nthreads-1)
{
    message++;
    printf("Process %i sends %i\n", tid, message);
    MPI_Send(&message, 1, MPI_INT, tid+1, 0, MPI_COMM_WORLD);
}
...

尽管message似乎确实增加到3以上,但这样做还不错。为什么会这样?

3 个答案:

答案 0 :(得分:2)

MPI排名不是线程,它们是 - 好 - “排名”,或者MPI说的有时候处理元素,但是流程一般来说。

这通常是一个小细节,但在这里我认为它实际上反映了潜在的混乱。如果在OpenMP(比如说)中你有以下代码

int message = 0;

#pragma omp parallel default(none) shared(message)
{
   int tid = omp_get_thread_num();
   if (tid != nthreads-1) {
       #pragma omp atomic
       message++;
   }
}

然后在并行部分的末尾,消息实际上已经增加了OMP_NUM_THREADS-1次。

但是MPI没有线程化;当您使用mpiexecmpirun启动程序时,将启动n个任务,并且每个任务在其自己的进程中运行完全相同的程序 - 例如,没有共享变量。特别是,每个任务都有自己的变量message,并且该变量在上面的代码片段中最多会增加一次,这意味着message最后总是2或3发布的代码。

答案 1 :(得分:2)

mpirun -np N命令启动N MPI进程,而不是具有N个线程的一个进程。在每个进程中,您有变量message,每个进程都有自己的变量设置为2.接下来的第0个进程将其message == 3发送到第1个进程。在它之后,第一个过程发送他自己的message == 3和第二个捕获它......

答案 2 :(得分:1)

我强烈怀疑您可以通过以下代码实现您的目标:

int message = 2;

if(tid != 0)
{
   MPI_Recv(&message, 1, MPI_INT, tid-1, 0, MPI_COMM_WORLD, &status);
   printf("Process %i receive %i\n", tid, message);
}

if(tid != nthreads-1)
{
   message++;
   printf("Process %i sends %i\n", tid, message);
   MPI_Send(&message, 1, MPI_INT, tid+1, 0, MPI_COMM_WORLD);
}

因此,每个过程(等级0除外)将从先前等级接收值,将其递增1然后将其传递到下一等级(除最后等级之外)。例如:

  • 排名0将2发送到排名1
  • 等级1从等级0接收2,递增它并将3发送到等级2
  • 排名2从排名1收到3,递增它并将4发送到排名3
  • ...
  • 排名 nthreads -1从排名 nthreads -2
  • 获得2+nthreads-1