MPI_Allgather的负缩放

时间:2015-02-02 18:46:47

标签: c runtime mpi

我正面临一个问题,因为我在C中编写并行分子动力学算法,其中所有核心计算最小的碰撞时间,然后通过MPI_Allgather将碰撞伙伴传递给所有其他核心以查看最早的碰撞。 我已经内置了一个时间测量功能,以查看我的程序的不同部分是如何缩放的。这表明,对于8个节点(192个核心),Allgather在100k时间步长上花费2000秒,而在20个节点(480)上花费5000秒。

我在Cray系统上使用带有以下标志的Cray编译器:

    add_definitions(-DNDEBUG)
    set(CMAKE_C_FLAGS "-O3 -h c99,pl=./compiler_information,wp")
    set(CMAKE_EXE_LINKER_FLAGS "-h pl=./compiler_information,wp") 

代码的一部分如下所示:

    MPI_Barrier(cartcomm);

    START(scmcdm_Allgather); // time measure
        MPI_Allgather(v_min_cpartner, 1, mpi_vector5, min_cpartners, 1, mpi_vector5, cartcomm);
    STOP(scmcdm_Allgather); // time measure

其中mpi_vector5是包含5个双精度段的连续数据类型:

MPI_Type_contiguous(5, MPI_DOUBLE, &mpi_vector5); 

这是正常行为吗?我该如何优化它?

更新: 感谢您的评论,我实施了另外两种解决问题的方法:

  1. 如果所有内核在给定的时间步长内实际发生冲突(只有少数会发生),则所有内核首先发送一个整数值,然后只有发生冲突的内核将其传递给核心0,然后核心0广播最小值。
  2. 这里第一步很慢,所有核心都与核心0通信.MPI是否有可能跳过这一步并有一个集体通信例程,其中只有部分核心参与? (即具有最小值的那些)

    1. 我使用了具有碰撞时间和等级的double_int对来使用minloc函数,而不是使用vector5进行通信。具有最小冲突时间的核心然后广播vector5。
    2. 这个解决方案到目前为止是最快的,但它仍然是负面扩展(8个节点上1600个,20个节点上3000个)。

      还有其他想法吗?

1 个答案:

答案 0 :(得分:1)

解决原始问题的问题:

  1. 让您的MPI变得简单。如果您有类似发送5个双打的内容,请避免使用数据类型。因此,如果您要发送5个双打,请说:MPI_Allgather(v_min_cpartner, 5, MPI_DOUBLE, min_cpartners, 5, MPI_DOUBLE, cartcomm)

    原因是遗憾的是,用户定义的MPI数据类型的情况可能并不总是被优化。

  2. 我假设您在操作完成等级0时正在打印。这是一种方式,但它可能会给您一个不完整的图片。最好的方法是为每个等级计时,然后运行MPI_Allreduce以查找所有等级报告的时间的最大值。

    集体操作在不同时间在不同的等级上完成,MPI实现在内部根据等级数,有效负载,机器分配大小等来更改算法。如果该等级在您的关键路径上,则计算特定等级的时间是有意义的MPMD计划;如果您正在执行SPMD程序,则必须等待下一次集体操作或同步点中花费时间最长的等级。