MPI_Sendrecv_replace函数非常耗时。

MPI_Sendrecv_replace函数非常耗时。,c,linux,performance,mpi,C,Linux,Performance,Mpi,我在代码中多次调用了MPI_Sendrecv_replace。但是函数的行为非常奇怪。在第一个循环(5000次迭代)中,MPI_Sendrecv_replace总共花费约30秒。但是,在第二个循环中,函数只使用了1秒。我对原因很好奇,因为我想优化代码。代码使用32个处理器运行。这台机器是一个带有4个Intel(R)Xeon(R)CPU E5-4620 v2的节点 我的部分代码如下: for (ishot=1;ishot<=nshots;ishot+=SHOTINC){ ...

我在代码中多次调用了MPI_Sendrecv_replace。但是函数的行为非常奇怪。在第一个循环(5000次迭代)中,MPI_Sendrecv_replace总共花费约30秒。但是,在第二个循环中,函数只使用了1秒。我对原因很好奇,因为我想优化代码。代码使用32个处理器运行。这台机器是一个带有4个Intel(R)Xeon(R)CPU E5-4620 v2的节点

我的部分代码如下:

for (ishot=1;ishot<=nshots;ishot+=SHOTINC){
    ...
    for (nt=1;nt<=NT;nt++){
         ...
         MPI_Sendrecv_replace(&bufferlef_to_rig[1][1],NY*fdo3,MPI_FLOAT,INDEX[1],TAG1,INDEX[2],TAG1,MPI_COMM_WORLD,&status);
         ...
    }
    for (nt=1;nt<=NT;nt++){
        ...
        MPI_Sendrecv_replace(&bufferlef_to_rig[1][1],NY*fdo3,MPI_FLOAT,INDEX[1],TAG1,INDEX[2],TAG1,MPI_COMM_WORLD,&status);
         ...
    }
}

用于(ishot=1;ishot问题似乎是MPI_Sendrecv_replace的性能缺陷。当我将MPI_Sendrecv_replace替换为MPI_Sendrecv时,程序运行正常,耗时的问题消失。我在和中找到了错误报告

问题似乎是MPI_Sendrecv_replace的性能缺陷MPI_Sendrecv_替换为MPI_Sendrecv,程序运行正常,耗时问题消失。我在和中发现了错误报告,当基本相同的阻塞通信操作完成的时间相差很大时,原因通常不是通信本身花费的时间多多少少;而是阻塞占用的时间或多或少。很有可能您看到的是负载不平衡,或者某些通信伙伴不同步。您是否看到跨MPI任务的sendrecv时间有变化?设置一个
MPI_屏障(MPI_COMM_WORLD)
在循环之前,看看这是否有什么变化。很抱歉,因为学校放假而没有回复。正如@HristoIliev所说,如果我在第一个循环中的
MPI\u Sendrecv\u replace
之前添加
MPI\u Barrier
几乎不花费时间。但是这种情况只发生在第一个循环中,也就是说,当我在第二个循环中添加
MPI_Barrier
时,没有任何变化。我忘记提到的一件事是,NY*fdo3*MPI_浮点的大小约为16KB。这是负载不平衡的问题吗?可能是负载不平衡导致不同的MPI列脱离sync。由于MPI\u Sendrecv\u replace操作正在同步,并且您可能有一个循环的依赖链,因此由于负载不平衡而导致的延迟将传播和累积。请使用MPI跟踪工具,如Vampir(商业软件)评估是否是这种情况。当基本上相同的阻塞通信操作完成的时间相差很大时,原因通常不是通信本身花费的时间多多少少;而是阻塞花费的时间多少少。很有可能您看到的是负载ce或某些通信伙伴不同步。您是否看到跨MPI任务的sendrecv时间有变化?设置一个
MPI\u屏障(MPI\u COMM\u WORLD)
在循环之前,看看这是否有什么变化。很抱歉,因为学校放假而没有回复。正如@HristoIliev所说,如果我在第一个循环中的
MPI\u Sendrecv\u replace
之前添加
MPI\u Barrier
几乎不花费时间。但是这种情况只发生在第一个循环中,也就是说,当我在第二个循环中添加
MPI_Barrier
时,没有任何变化。我忘记提到的一件事是,NY*fdo3*MPI_浮点的大小约为16KB。这是负载不平衡的问题吗?可能是负载不平衡导致不同的MPI列脱离sync。由于MPI\u Sendrecv\u replace操作正在同步,并且您可能有一个循环的依赖链,因此由于负载不平衡而导致的延迟将传播和累积。请使用MPI跟踪工具,如Vampir(商业软件)评估是否是这样。该假设无法解释为什么添加屏障会将Sendrecv_替换时间减少到几乎为零,而屏障需要30秒(!!)。我敢打赌,在这里使用MPI_Sendrecv而不是Sendrecv_replace的性能几乎完全相同。这里的问题是某种同步问题,可能是负载不平衡;@HristoIlliev建议使用跟踪工具来找出发生了什么,这是正确的方法。请注意,免费软件scalasca将为您确定负载不平衡,您可以使用MPE+Jumpshot作为免费软件跟踪器。此假设无法解释为什么添加屏障会将Sendrecv_更换时间减少到几乎为零,并且屏障需要30秒(!!)。我敢打赌,在这里使用MPI_Sendrecv而不是Sendrecv_replace的性能几乎完全相同。这里的问题是某种同步问题,可能是负载不平衡;@HristoIlliev建议使用跟踪工具来找出发生了什么,这是正确的方法。请注意,免费软件scalasca将为您确定负载不平衡,您可以使用MPE+Jumpshot作为免费软件跟踪器。