为什么 MPI_Win_unlock 这么低?
Why MPI_Win_unlock is so low?
我的应用程序使用单向通信(MPI_Rget、MPI_Raccumulate)和 MPI_Win_Lock 和 MPI_Win_Unlock 等同步原语来实现其被动目标同步。
我分析了我的应用程序,发现大部分时间花在了 MPI_Win_Unlock 函数上(而不是 MPI_Win_Lock),我不明白这是为什么。
(1) 有谁知道为什么 MPI_Win_Unlock 函数要花这么多时间? (也许是执行问题)
(2) 如果我转向 S/C/P/W 同步模型,这种情况会好转吗?
我只需要确保所有的单边操作没有同时重叠。
我正在使用英特尔的 MPI 库版本 5.1,它实现了 MPI V3。
我附上了一些我的代码片段(实际上就是所有的:D)
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)
函数MPI_Win_unlock
将阻塞,直到访问时期的所有RMA操作都完成。
因此,您的探查器会显示此函数占用大部分时间也就不足为奇了。它将阻塞直到 MPI 实现完成所有 one-sided 自相应 MPI_Win_lock
.
以来发布的通信操作
请注意,one-sided 操作(Put、Get 等)只会分派操作,在操作完成之前不会阻塞。因此,这些操作实际上非常类似于没有 MPI_Request
对象的 non-blocking 通信功能(MPI_Isend
/MPI_Irecv
)。继续类比,MPI_Win_unlock
等待所有操作完成,类似于 MPI_Wait_all
.
我的应用程序使用单向通信(MPI_Rget、MPI_Raccumulate)和 MPI_Win_Lock 和 MPI_Win_Unlock 等同步原语来实现其被动目标同步。
我分析了我的应用程序,发现大部分时间花在了 MPI_Win_Unlock 函数上(而不是 MPI_Win_Lock),我不明白这是为什么。
(1) 有谁知道为什么 MPI_Win_Unlock 函数要花这么多时间? (也许是执行问题) (2) 如果我转向 S/C/P/W 同步模型,这种情况会好转吗? 我只需要确保所有的单边操作没有同时重叠。
我正在使用英特尔的 MPI 库版本 5.1,它实现了 MPI V3。
我附上了一些我的代码片段(实际上就是所有的:D)
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)
函数MPI_Win_unlock
将阻塞,直到访问时期的所有RMA操作都完成。
因此,您的探查器会显示此函数占用大部分时间也就不足为奇了。它将阻塞直到 MPI 实现完成所有 one-sided 自相应 MPI_Win_lock
.
请注意,one-sided 操作(Put、Get 等)只会分派操作,在操作完成之前不会阻塞。因此,这些操作实际上非常类似于没有 MPI_Request
对象的 non-blocking 通信功能(MPI_Isend
/MPI_Irecv
)。继续类比,MPI_Win_unlock
等待所有操作完成,类似于 MPI_Wait_all
.