2013-08-28 133 views
2

从阅读文档,MPI_Bcast是一个阻塞调用(因此boost :: mpi :: broadcast)也是如此。衡量根节点广播花费的时间量是衡量数据从根节点到所有其他节点所花费的时间的一个很好的衡量标准吗?打开MPI广播延迟测量

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; 

回答

2

MPI_BCAST,他们已经完成了他们的一部分后,通常是在某种树的时尚,其中在树的顶端过程可以退出算法来实现的广播。因此,如果等级0将消息发送给等级1和等级n/2,那么在这些消息完成后它可以离开。所以你的问题的答案是:不,这不是一个准确的测量。

如果没有精确同步的时钟,实际测量完整广播跨越所有节点的时间很困难。有些技巧可以做得更近(在开始时间使用MPI_BARRIER进行同步,并使用广播中的任何进程花费的最长时间),但由于时钟仍倾向于有一些漂移,所以没有什么是完美的。

+0

谢谢,简洁明白的答案。这个技巧也帮助我们找出了一个我们不知道的节点同步问题。 – jekelija

1

你错了阻止全局同步调用。保证全局同步的唯一集体MPI操作是MPI_BARRIER - 除非所有进程都调用它,否则它不会完成。只要进行呼叫的流程不需要进一步参与,MPI就允许其他集体呼叫立即返回。

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

  • 基本线性 - 这一个采用了一束MPI_ISEND秒,然后MPI_WAITALL,因此完成一次所有发送已经完成并且信息已经达到了所有其他等级;
  • 二进制/二叉树 - 一旦消息已传输到根节点的直接后代的队列,则完成一次;它仍然需要更多时间才能到达树中的所有节点;
  • 流水线 - 这个分割消息并实现一个流水线,它将根段之后的段从下一层传递到下一层,然后将它们交给下一层等,在大量消息和非常快的网络(例如InfiniBand)中完成根中的操作意味着全球完成即将到来;
  • 链 - 它将进程划分为几个组,然后为每个组实现单独的管道。

可以实施一定的算法由开放MPI使用 - 只要看看在coll_tuned_bcast_algorithm MCA参数的可能值和其它相关参数:

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

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