使第一个过程异步到达某个点

时间:2019-02-16 15:30:09

标签: mpi

我的程序从每个进程开始做一些工作开始,最后应该收集结果并计算最终结果。现在,每个人都将数据发送到proc 0,它是执行最终计算任务的人。我想找到一个在完成本地任务的第一个过程中执行此操作。

找到这个过程并异步告知所有其他过程是否有技巧?我当时在考虑使用异步集体操作,但是找不到一种方法。

谢谢, 偷

1 个答案:

答案 0 :(得分:1)

正如Gilles所说,您可以使用单面操作(useful docs)来设置一个变量,该变量将包含首先完成的进程的等级。您将变量设置为-1,当一个进程完成时,它使用一侧读取该变量(首先考虑阻止其他进程访问以避免种族),如果它为-1,则该进程将其设置为他的等级,如果它是一个数字> = 0,则成为“主”,然后该进程成为(该数字的)从属。

(正如吉尔斯指出的那样:在版本> 3.0中,可以使用MPI_Compare_and_swap一次执行“获取和放置”操作(这可能比“获取”之后放置“放置”要快))

仅当您在进程之间的执行时间和少量进程之间存在真正的差异时,此方法才能正常工作。因此,在浪费时间实施这种解决方案时应该小心。如果您有很大的负载不平衡(并且不能重新设计并行化以增加负载平衡),那就可以了! 然后,如果您的目标是> 10个流程,最好先将所有流程分组在一个嵌套的子组网格中。然后在每个组级别上执行技巧(避免让100k进程尝试读取相同的变量并浪费大量时间!)

这是一个简单的代码可以实现...

  #include <mpi.h>
  #include <thread>
  #include <chrono>
  #include <stdlib.h>
  #include <iostream>
  #include <time.h>


  using namespace std;

  int main(int argc, char** argv) {

      MPI_Init(NULL, NULL);

      int rank;
      MPI_Comm_rank(MPI_COMM_WORLD, &rank);

      srand (time(NULL)+rank);
      int wt = rand() % 5 + 1;
      cout <<"rank: "<< rank<< " sleep: "<< wt<<endl;



      //here is the magic...

      int * flag;
      MPI_Win window;
      int master;
      int compare = -1;
      MPI_Win_allocate(sizeof(int), sizeof(int),MPI_INFO_NULL,
                       MPI_COMM_WORLD, &flag, &window );


      *flag = -1;
      this_thread::sleep_for(chrono::seconds(wt));


      MPI_Win_lock (MPI_LOCK_EXCLUSIVE, 0, 0, window);
      MPI_Compare_and_swap(&rank, &compare, &master, MPI_INT, 0,0, window);
      MPI_Win_unlock (0, window);


      if(master == -1)
      {
        cout<< "rank: "<<rank<<". I am the master"<<endl;
      }
      else
      {
        cout<< "rank: "<<rank<<". I am the slave of "<<master<<endl;
      }


      MPI_Win_free( &window );
      MPI_Finalize();
  }

输出:

mpirun --oversubscribe  -np 4 ./test
rank: 2 sleep: 4
rank: 3 sleep: 1
rank: 0 sleep: 5
rank: 1 sleep: 2
rank: 3. I am the master
rank: 1. I am the slave of 3
rank: 2. I am the slave of 3
rank: 0. I am the slave of 3
mpirun --oversubscribe  -np 4 ./test
rank: 0 sleep: 2
rank: 1 sleep: 4
rank: 2 sleep: 1
rank: 3 sleep: 3
rank: 2. I am the master
rank: 0. I am the slave of 2
rank: 3. I am the slave of 2
rank: 1. I am the slave of 2