gpt4 book ai didi

c - MPI_Allgather 的负缩放

转载 作者:太空狗 更新时间:2023-10-29 15:40:38 25 4
gpt4 key购买 nike

我在用 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 个 double 值的连续数据类型:

MPI_Type_contiguous(5, MPI_DOUBLE, &mpi_vector5); 

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

更新:感谢您的意见,我实现了其他 2 种解决问题的方法:

  1. 如果所有核心在给定的时间步长内确实发生了碰撞(只有少数会发生),则所有核心首先发送一个整数值,然后只有发生碰撞的核心将其传达给核心 0,然后核心 0 广播最小值。

这里的第一步很慢,所有内核都与内核 0 进行通信。MPI 中是否有可能跳过此步骤并拥有一个只有部分内核参与的集体通信例程? (即具有最小值的那些)

  1. 我没有使用 vector5 来通信,而是使用带有碰撞时间和等级的 double_int 对来使用 minloc 函数。碰撞时间最短的核心然后广播 vector5。

此解决方案是迄今为止最快的解决方案,但它仍然会出现负扩展(8 个节点上为 1600 秒,20 个节点上为 3000 秒)。

还有其他想法吗?

最佳答案

解决原始问题的问题:

  1. 让您的 MPI 保持简单。如果您要发送 5 个 double ,请避免使用数据类型。因此,如果您要发送 5 个 double ,请这样说:MPI_Allgather(v_min_cpartner, 5, MPI_DOUBLE, min_cpartners, 5, MPI_DOUBLE, cartcomm)

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

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

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

关于c - MPI_Allgather 的负缩放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28284599/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com