我有一个非常简单的代码,一个数据分解问题,其中在一个循环中,每个进程在每个循环之前和之后向队列发送两条大消息。我在 SMP 节点集群(AMD Magny 内核,每个节点 32 个内核,每个插槽 8 个内核)中运行此代码。有一段时间我正在优化这段代码。我使用 pgprof 和 tau 进行分析,在我看来瓶颈是通信。我试图将通信与我的代码中的计算重叠,但是看起来实际通信是在计算完成时开始的:(
我在就绪模式 (MPI_Rsend_init) 下使用持久通信,并且在 MPI_Start_all 和 MPI_Wait_all 之间完成了大部分计算。代码如下所示:
void main(int argc, char *argv[])
{
some definitions;
some initializations;
MPI_Init(&argc, &argv);
MPI_Rsend_init( channel to the rank before );
MPI_Rsend_init( channel to the rank after );
MPI_Recv_init( channel to the rank before );
MPI_Recv_init( channel to the rank after );
for (timestep=0; temstep<Time; timestep++)
{
prepare data for send;
MPI_Start_all();
do computations;
MPI_Wait_all();
do work on the received data;
}
MPI_Finalize();
}
不幸的是,实际数据传输直到计算完成才开始,我不明白为什么。该网络使用 QDR InfiniBand 互连和 mvapich2。每条消息大小为 23MB(总共发送 46MB 消息)。我试图将消息传递更改为急切模式,因为系统中的内存足够大。我在作业脚本中使用以下标志: MV2_SMP_EAGERSIZE=46M
MV2_CPU_BINDING_LEVEL=socket
MV2_CPU_BINDING_POLICY=bunch
这给了我大约 8% 的改进,可能是因为在 SMP 节点内更好地放置了等级,但是仍然存在通信问题。我的问题是为什么我不能有效地将通信与计算重叠?是否有任何我应该使用的标志并且我错过了它?我知道有些不对劲,但我所做的一切都还不够。
按照 SMP 节点内的等级顺序,节点之间的实际消息大小也是 46MB (2x23MB),并且等级处于循环中。你能帮我么?要查看其他用户使用的标志,我检查了 /etc/mvapich2.conf 但它是空的。
还有其他我应该使用的方法吗?你认为单方面的沟通会带来更好的表现吗?我觉得有一面旗帜或我不知道的东西。
非常感谢。