为什么MPI_Win_unlock这么低?

为什么MPI_Win_unlock这么低?,mpi,Mpi,我的应用程序使用单边通信(MPI_Rget、MPI_Raccumulate)和MPI_Win_Lock和MPI_Win_Unlock等同步原语进行被动目标同步 我分析了我的应用程序,发现大部分时间都花在MPI_Win_解锁功能(而不是MPI_Win_Lock)上,我不明白为什么 (1) 有人知道为什么MPI_Win_解锁功能需要这么多时间吗?(可能是实施问题) (2) 如果我移动S/C/P/W同步模型,这种情况会变得更好吗? 我只需要确保所有单边操作不会同时重叠 我使用的是英特尔的MPI库5.1

我的应用程序使用单边通信(MPI_Rget、MPI_Raccumulate)和MPI_Win_Lock和MPI_Win_Unlock等同步原语进行被动目标同步

我分析了我的应用程序,发现大部分时间都花在MPI_Win_解锁功能(而不是MPI_Win_Lock)上,我不明白为什么

(1) 有人知道为什么MPI_Win_解锁功能需要这么多时间吗?(可能是实施问题) (2) 如果我移动S/C/P/W同步模型,这种情况会变得更好吗? 我只需要确保所有单边操作不会同时重叠

我使用的是英特尔的MPI库5.1版,它实现了MPI V3

我附加了一些代码片段(实际上都是:D)


功能
MPI_Win_unlock
将阻塞,直到访问历元的所有RMA操作完成

因此,毫不奇怪,您的分析器会显示此函数占用大部分时间。它将一直阻止,直到MPI实现完成自相应的
MPI\u Win\u lock
以来发布的所有单边通信操作


请注意,单边操作(Put、Get等)只会分派操作,在操作完成之前不会阻塞。因此,这些操作实际上非常类似于无
MPI\u请求
对象的非阻塞通信功能(
MPI\u Isend
/
MPI\u Irecv
)。继续类推,
MPI\u Win\u unlock
等待所有操作完成,类似于
MPI\u Wait\u all

感谢您的解释。这就解释了这些数字。这是否意味着我过于保守地强制同步?如果我使用S/C/P/W同步原语,它会得到改进吗?S/C/P/W同步是否会更快取决于您的应用程序。与MPI_Fence的活动目标同步可能是最简单的选择,它允许Fence之间的所有访问。如果需要更严格的同步,如果通信模式保持简单(例如,每个进程仅与几个邻居通信),则S/C/P/W应该更快。如果每个进程可以与许多其他进程通信,
lock
/
unlock
可能会更快。只有测试不同的选项,您才能为应用程序确定性能最佳的选项;)不可以。不要使用PSCW。如果这是您的模式,请使用Send-Recv。PSCW真的那么糟糕吗?你会说发送/接收通常比PSCW快吗?PSCW可能对累积操作有用,但我不知道有人试图使用这个…请分享代码。我可以提供帮助,但不能没有MCVE。请在启用异步进度的情况下重试。环境变量应该很容易通过谷歌找到。@Jeff,谢谢Jeff,我添加了一些代码片段。在这里设置“MPICH\u ASYNC\u PROGRESS=1”效果很好。它将花费在“MPI_Win_Unlock”上的时间减少了50%。现在我对MPI标准中的术语“单边通信”非常怀疑……MPI标准拒绝保证异步。我已经对此进行了斗争,但这可能仍然是一个实施质量问题。请参阅来自Argonne的Casper项目,了解如何比使用线程更有效地执行异步进程。完全公开:我是Casper的合著者和主要用户。顺便说一句,如果你在之后立即与Unlock同步,你不应该使用Rget。使用Get。目标的使用仅限于数据流类型的使用。
Each MPI process runs 'Run()'

Run ()
 // Join
 For each Target_Proc i in MPI_COMM_WORLD
  RequestDataFrom ( (i + k) % nprocs ); // requests k-step away neighbor's data asynchronously
  ConsumeDataFrom (i); 
  JoinWithMyData (my_rank, i);
  WriteBackDataTo (i);

 goto the above 'For loop' again if the termination condition does not hold. 
 MPI_Barrier(MPI_COMM_WORLD);

 // Update Data in Window
 UpdateMyWindow (my_rank);

RequstDataFrom (target_rank_id)
 MPI_Win_Lock (MPI_LOCK_SHARED, target_rank_id, win)
 MPI_Rget (from target_rank_id, win, &requests[target_rank_id])
 MPI_Win_Unlock (target_rank_id, win)

ConsumeDataFrom (target_rank_id)
 MPI_Wait (&requests[target_rank_id])
 GetPointerToBuffer (target_rank_id)

WriteBackDataTo (target_rank_id)
 MPI_Win_Lock (MPI_LOCK_EXCLUSIVE, target_rank_id, win)
 MPI_Rput (from target_rank_id, win, &requests[target_rank_id])
 MPI_Win_Unlock (target_rank_id, win)

UpdateMyWindow ()
 MPI_Win_Lock (MPI_LOCK_EXCLUSIVE, target_rank_id, win)
 Update()
 MPI_Win_Unlock (target_rank_id, win)