我正面临一个问题,因为我在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);
这是正常行为吗?我该如何优化它?
更新: 感谢您的评论,我实施了另外两种解决问题的方法:
这里第一步很慢,所有核心都与核心0通信.MPI是否有可能跳过这一步并有一个集体通信例程,其中只有部分核心参与? (即具有最小值的那些)
这个解决方案到目前为止是最快的,但它仍然是负面扩展(8个节点上1600个,20个节点上3000个)。
还有其他想法吗?
答案 0 :(得分:1)
解决原始问题的问题:
让您的MPI变得简单。如果您有类似发送5个双打的内容,请避免使用数据类型。因此,如果您要发送5个双打,请说:MPI_Allgather(v_min_cpartner, 5, MPI_DOUBLE, min_cpartners, 5, MPI_DOUBLE, cartcomm)
原因是遗憾的是,用户定义的MPI数据类型的情况可能并不总是被优化。
我假设您在操作完成等级0时正在打印。这是一种方式,但它可能会给您一个不完整的图片。最好的方法是为每个等级计时,然后运行MPI_Allreduce
以查找所有等级报告的时间的最大值。
集体操作在不同时间在不同的等级上完成,MPI实现在内部根据等级数,有效负载,机器分配大小等来更改算法。如果该等级在您的关键路径上,则计算特定等级的时间是有意义的MPMD计划;如果您正在执行SPMD程序,则必须等待下一次集体操作或同步点中花费时间最长的等级。