【问题标题】:The MPI_Sendrecv_replace function is excessively time consuming.MPI_Sendrecv_replace 函数非常耗时。
【发布时间】:2015-09-29 06:00:40
【问题描述】:

我在代码中多次调用了 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);
         ...
    }
}

我使用 MPI_Wtime 来计算 MPI_Sendrecv_replace 花费的时间。

【问题讨论】:

  • 当您完成基本相同的阻塞通信操作的时间差别很大时,原因通常不是通信本身花费的时间或多或少;这是阻塞花费或多或少的时间。您所看到的很有可能是负载不平衡,或者某些通信伙伴不同步。您是否看到 MPI 任务的 sendrecv 时间有所不同?
  • 在循环之前放一个MPI_Barrier(MPI_COMM_WORLD);,看看是否有任何改变。
  • 由于学校放假没有回复,抱歉。正如@HristoIliev 所说,如果我在第一个循环中在MPI_Sendrecv_replace 之前添加MPI_Barrier,则MPI_Barrier 的时间成本约为30 秒,而MPI_Sendrecv_replace 几乎不需要时间。但是这种情况只发生在第一个循环中,即当我在第二个循环中添加MPI_Barrier 时没有变化。我忘记提及的一件事是 NY*fdo3*MPI_FLOAT 的大小约为 16Kbytes。是负载不平衡的问题吗?
  • 也许您遇到了负载不平衡的情况,导致不同的 MPI 等级在时间上不同步。因为MPI_Sendrecv_replace 操作正在同步,并且您可能有一个循环依赖链,所以由于负载不平衡而导致的延迟将传播和累积。使用像 Vampir(商业软件)这样的 MPI 跟踪工具来评估是否是这种情况。

标签: c linux performance mpi


【解决方案1】:

问题似乎是 MPI_Sendrecv_replace 的性能错误。当我用 MPI_Sendrecv 替换 MPI_Sendrecv_replace 时,程序运行正常,耗时问题消失。我在https://github.com/open-mpi/ompi/issues/93http://www.open-mpi.org/community/lists/users/2010/01/11683.php 中找到了错误报告

【讨论】:

  • 这个假设不能解释为什么添加屏障可以将 Sendrecv_replace 时间减少到几乎为零,而屏障需要 30 秒 (!!)。我敢打赌,您在这里使用 MPI_Sendrecv 而不是 Sendrecv_replace 最终具有几乎完全相同的性能。这里的问题是某种同步问题,可能是负载不平衡; @HristoIlliev 建议使用跟踪工具找出正在发生的事情是正确的方法。请注意,免费软件 scalasca 会为您识别负载不平衡,您可以使用 MPE+Jumpshot 作为免费软件跟踪器。
猜你喜欢
  • 1970-01-01
  • 2016-07-04
  • 2014-12-13
  • 1970-01-01
  • 2021-01-10
  • 1970-01-01
  • 2017-12-06
  • 2014-11-07
  • 1970-01-01
相关资源
最近更新 更多