2

通过阅读文档,MPI_Bcast 也是一个阻塞调用(因此 boost::mpi::broadcast)也是如此。测量根节点广播所需的时间是否可以很好地衡量数据从根节点到所有其他节点所需的时间?

IE

int64_t t1 = Utility::picosecondTime(); //exactly what it sounds like; utility that measures current time in picoseconds
boost::mpi::broadcast(communicator, variable, 0);
std::cout << "Broadcast took " << Utility::picosecondTime()-t1 << std::endl;

或者对于直接的 OpenMPI:

MPI_Comm comm; 
int array[100]; 
...
int64_t t1 = Utility::picosecondTime(); 
MPI_Bcast( array, 100, MPI_INT, 0, comm); 
std::cout << "Broadcast took " << Utility::picosecondTime()-t1 << std::endl;
4

2 回答 2

3

AnMPI_BCAST通常以某种树的方式实现,其中树顶部的进程可以在完成其广播部分后退出算法。因此,如果 rank 0 向 rank 1 和 n/2 发送消息,那么它可以在这些消息完成后离开。所以你的问题的答案是:不,这不是一个准确的测量。

如果没有准确同步的时钟,就很难实际测量一次完整广播在所有节点上花费的时间。您可以采取一些技巧来接近(MPI_BARRIER在获取开始时间之前使用同步并使用广播中任何进程花费的最长时间),但由于时钟仍然倾向于有一些漂移,因此没有什么是完美的。

于 2013-08-28T21:20:26.750 回答
1

您误认为阻塞全局同步调用。唯一保证全局同步的集体 MPI 操作是MPI_BARRIER- 除非所有进程都调用它,否则它不会完成。只要发出调用的进程不需要进一步参与,MPI 就允许其他集体调用返回。

MPI_BCAST几乎是后者的一个例子。Open MPI 提供了几种实现方式,其中包括:基本线性、二叉树、二叉树和管道/链。每个实现都可以进一步分割消息。在运行时使用硬编码启发式方法来根据消息大小和通信器的大小选择一个特定的实现。从根等级的角度来看,相同的广播操作可能会根据所使用的算法花费不同的时间。

  • 基本线性 - 这个使用一堆MPI_ISENDs 后跟MPI_WAITALL,因此仅在所有发送完成并且信息已到达所有其他等级后才完成;
  • 二叉树/二叉树 - 一旦消息被传输到作为根节点的直接后代的行列,这个树就完成了;它可能仍然需要更多时间才能到达树中的所有节点;
  • 管道 - 这个对消息进行分段并实现一个管道,将段从根级别传递到它之后的下一个,然后将它们传递到下一个,依此类推;对于大消息和非常快的网络(例如 InfiniBand),根中操作的完成意味着全局完成几乎迫在眉睫;
  • 链 - 这个将流程分成几个组,然后为每个组实现一个单独的管道。

您可以强制 Open MPI 使用某种算法 - 只需查看coll_tuned_bcast_algorithmMCA 参数和其他相关参数的可能值:

$ ompi_info --mca coll_tuned_use_dynamic_rules 1 --param coll tuned | grep bcast

测量时间的正确方法MPI_BCAST是用MPI_BARRIER调用包围它,但你还必须正确测量屏障调用本身的开销,然后对其进行补偿。

于 2013-09-02T15:00:08.533 回答