使用MPI_Barrier()后,MPI_Wtime()出现巨大差异

Huge difference in MPI_Wtime() after using MPI_Barrier()?

本文关键字:MPI 巨大 Barrier 使用 Wtime      更新时间:2023-10-16

这是代码的一部分。

    if(rank==0) {   
        temp=10000; 
        var=new char[temp] ;
        MPI_Send(&temp,1,MPI_INT,1,tag,MPI_COMM_WORLD); 
        MPI_Send(var,temp,MPI_BYTE,1,tag,MPI_COMM_WORLD);
            //MPI_Wait(&req[0],&sta[1]);
    }
    if(rank==1) {
        MPI_Irecv(&temp,1,MPI_INT,0,tag,MPI_COMM_WORLD,&req[0]);
        MPI_Wait(&req[0],&sta[0]);
        var=new char[temp] ;
        MPI_Irecv(var,temp,MPI_BYTE,0,tag,MPI_COMM_WORLD,&req[1]);
        MPI_Wait(&req[0],&sta[0]);
    }
    //I am talking about this MPI_Barrier

    MPI_Barrier(MPI_COMM_WORLD);
    cout << MPI_Wtime()-t1 << endl ;
    cout << "hello " << rank  << " " << temp << endl ;
        MPI_Finalize();
}

1.当使用MPI_Barrier时-正如预期的那样,所有过程花费的时间几乎相同,大约为0.02

2.当不使用MPI_Barrier()时-根进程(发送消息)等待一些额外的时间。并且CCD_ 1变化很大并且根处理所花费的时间大约为2秒。

如果我没有错的话,MPI_Barrier只用于将所有正在运行的进程置于同一级别。那么,为什么我使用MPI_Barrier()的时间不为2秒(所有进程中的最小值,例如root进程)呢。请解释一下?

感谢Wesley Bland注意到您在同一请求上等待了两次。以下是对实际发生的事情的解释。

MPI中的异步(非阻塞)操作称为进程。那就是实际转移发生的时候。在MPI库中,进程可以以许多不同的方式和在许多不同的点上进行。发布异步操作时,其进程可能会无限期推迟,甚至直到调用MPI_WaitMPI_Test或某些会导致新消息被推送到发送/接收队列或从中拉出的调用。这就是为什么在非阻塞操作启动后尽快调用MPI_WaitMPI_Test非常重要。

Open MPI支持后台进程线程,即使不满足上一段中的条件(例如,从未在请求句柄上调用MPI_WaitMPI_Test),该线程也会小心地执行操作。在构建库时,必须显式启用此功能。默认情况下不会启用它,因为后台进程会增加操作的延迟。

在您的情况下,当您在接收器中第二次调用MPI_Wait时,您正在等待错误的请求,因此第二次MPI_Irecv操作的进程被推迟。消息大小超过40 KiB(10000乘以4字节+信封开销),高于Open MPI中的默认热切限制(32 KiB)。这样的消息是使用会合协议发送的,该协议要求发布和进行发送和接收操作。接收操作没有进展,因此秩0中的发送操作块,直到在某个时间点,秩1中的(MPI_Wtime -t1)0调用的清理例程最终进行接收。

当您对MPI_Barrier进行调用时,它会导致未完成接收的进行,其行为几乎就像对MPI_Wait的隐式调用。这就是为什么发送秩0很快完成,并且两个进程都能及时继续。

注意,紧接着MPI_WaitMPI_Irecv相当于简单地调用MPI_Recv。后者不仅更简单,而且不太容易出现像你所做的那种简单的打字错误。

您正在两次等待同一请求以获得Irecv。第二个是一个需要所有时间的排名,由于它被跳过,排名0遥遥领先。

MPI_BARRIER可以实现为,如果进程进入算法,则某些进程可以先于其他进程离开算法。这可能就是这里发生的情况。

在我运行的测试中,我发现运行时几乎没有差异。主要的区别是,你似乎只运行了一次代码,而我在你的代码上循环了数千次,然后取了平均值。我的输出如下:

With the barrier
[0]: 1.65071e-05
[1]: 1.66872e-05
Without the barrier
[0]: 1.35653e-05
[1]: 1.30711e-05

所以我认为你看到的任何变化都是你的操作系统的结果,而不是你的程序。

此外,为什么要将MPI_Irecv与MPI_wait结合使用,而不仅仅是使用MPI_recv?