【问题标题】:MPI Broadcast Very SlowMPI 广播非常慢
【发布时间】:2014-10-25 00:38:11
【问题描述】:

我正在编写一个 MPI 程序,而 MPI_Bcast 函数在我使用的一台特定机器上非常慢。为了缩小问题范围,我有以下两个测试程序。第一个执行从进程 0 到其他进程的许多 MPI_Send/MPI_Recv 操作:

#include <stdlib.h>
#include <stdio.h>
#include <mpi.h>

#define N 1000000000

int main(int argc, char** argv) {
  int rank, size;

  /* initialize MPI */
  MPI_Init(&argc, &argv);

  /* get the rank (process id) and size (number of processes) */
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  MPI_Comm_size(MPI_COMM_WORLD, &size);

  /* have process 0 do many sends */
  if (rank == 0) {
    int i, j;
    for (i = 0; i < N; i++) {
      for (j = 1; j < size; j++) {
        if (MPI_Send(&i, 1, MPI_INT, j, 0, MPI_COMM_WORLD) != MPI_SUCCESS) {
          printf("Error!\n");
          exit(0);
        }   
      }   
    }   
  }   

  /* have the rest receive that many values */
  else {
    int i;
    for (i = 0; i < N; i++) {
      int value;
      if (MPI_Recv(&value, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE) != MPI_SUCCESS) {
        printf("Error!\n");
        exit(0);
      }   
    }   
  }   

  /* quit MPI */
  MPI_Finalize( );
  return 0;
}

这个程序只用了 2.7 秒左右,有 4 个进程。

下一个程序做同样的事情,除了它使用 MPI_Bcast 将值从进程 0 发送到其他进程:

#include <stdlib.h>
#include <stdio.h>
#include <mpi.h>

#define N 1000000000

int main(int argc, char** argv) {
  int rank, size;

  /* initialize MPI */
  MPI_Init(&argc, &argv);

  /* get the rank (process id) and size (number of processes) */
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  MPI_Comm_size(MPI_COMM_WORLD, &size);

  /* have process 0 do many sends */
  if (rank == 0) {
    int i, j;
    for (i = 0; i < N; i++) {
      if (MPI_Bcast(&i, 1, MPI_INT, 0, MPI_COMM_WORLD) != MPI_SUCCESS) {
        printf("FAIL\n");
        exit(0);
      }   
    }   
  }   

  /* have the rest receive that many values */
  else {
    int i;
    for (i = 0; i < N; i++) {
      if (MPI_Bcast(&i, 1, MPI_INT, 0, MPI_COMM_WORLD) != MPI_SUCCESS) {
        printf("FAIL\n");
        exit(0);
      }   
    }   
  }   

  /* quit MPI */
  MPI_Finalize( );
  return 0;
}

两个程序的 N 值相同,并且两个程序都没有从通信调用中返回错误。第二个程序应该至少快一点。但事实并非如此,它在大约 34 秒时要慢得多 - 大约慢 12 倍!

这个问题只出现在一台机器上,而不是其他机器上,即使它们运行相同的操作系统 (Ubuntu) 并且没有完全不同的硬件。另外,我在两者上都使用 OpenMPI。

我真的要拔头发了,有人知道吗?

感谢阅读!

【问题讨论】:

    标签: mpi


    【解决方案1】:

    几个观察。

    MPI_Bcast 正在将结果接收到“&i”缓冲区。 MPI_Recv 将结果接收到“&value”中。做出这个决定有什么原因吗?

    发送/接收模型自然会同步。 MPI_Send 调用是阻塞和序列化的。当调用 MPI_Send 时,匹配的 MPI_Recv 应该始终准备好。

    一般来说,随着工作规模的扩大,集体往往具有更大的优势。

    我使用 IBM Platform MPI 编译并运行了这些程序。我将 N 值降低了 100 倍至 1000 万,以加快测试速度。我更改了 MPI_Bcast 以在“&value”缓冲区中接收结果,而不是在“&i”缓冲区中接收结果。我将每个案例运行了 3 次,然后取平均值。时间是“时间”返回的“真实”值(这是必要的,因为队伍是从 mpirun 命令远程运行的)。

    共享内存有 4 个等级,Send/Recv 模型耗时 6.5 秒,Bcast 模型耗时 7.6 秒。

    对于 32 个秩(8/节点 x 4 个节点,FDR InfiniBand),Send/Recv 模型耗时 79 秒,Bcast 模型耗时 22 秒。

    在 128 个秩(16/节点 x 8 节点,FDR Infiniband)中,Send/Recv 模型耗时 134 秒,Bcast 模型耗时 44 秒。

    鉴于在 N 值减少 100 倍至 10000000 之后的这些时间,我将建议“2.7 秒”时间是空操作。仔细检查是否完成了一些实际工作。

    【讨论】:

      猜你喜欢
      • 2014-05-07
      • 2020-04-01
      • 2011-12-31
      • 2013-09-27
      • 1970-01-01
      • 1970-01-01
      • 2022-09-23
      • 1970-01-01
      相关资源
      最近更新 更多