【问题标题】:Probe seems to consume the CPU探针似乎消耗 CPU
【发布时间】:2013-01-11 17:07:29
【问题描述】:

我有一个 MPI 程序,它由一个主进程组成,它将命令传递给一堆从进程。收到命令后,从站只需调用 system() 即可。当从站等待命令时,它们会消耗 100% 的各自 CPU。 Probe() 似乎处于一个紧密的循环中,但这只是一个猜测。您认为这可能是什么原因造成的,我可以做些什么来解决它?

这是从属进程中等待命令的代码。同时查看日志和top命令表明,当slave正在消耗它们的CPU时,它们就在这个函数内。

MpiMessage
Mpi::BlockingRecv() {
  LOG(8, "BlockingRecv");

  MpiMessage result;
  MPI::Status status;

  MPI::COMM_WORLD.Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, status);
  result.source = status.Get_source();
  result.tag = status.Get_tag();

  int num_elems = status.Get_count(MPI_CHAR);
  char buf[num_elems + 1];
  MPI::COMM_WORLD.Recv(
     buf, num_elems, MPI_CHAR, result.source, result.tag
  );
  result.data = buf;
  LOG(7, "BlockingRecv about to return (%d, %d)", result.source, result.tag);
  return result;
}

【问题讨论】:

  • 请注意,在具有 OpenFabrics 互连(InfiniBand 或 iWARP)的系统上调用 fork() 时,您应该注意可能的分段错误。

标签: mpi openmpi


【解决方案1】:

是的;出于性能考虑,大多数 MPI 实现都在阻塞操作上忙等待。假设 MPI 作业是我们在处理器上唯一关心的事情,如果任务被阻塞等待通信,最好的办法是不断轮询该通信以减少延迟;这样在消息到达和移交给 MPI 任务之间几乎没有延迟。这通常意味着即使没有“真正”做任何事情,CPU 也会保持在 100%。

对于大多数 MPI 用户来说,这可能是最好的默认行为,但它并不总是您想要的。通常 MPI 实现允许关闭它;使用 OpenMPI,you can turn this behaviour off with an MCA parameter,

mpirun -np N --mca mpi_yield_when_idle 1 ./a.out

【讨论】:

  • 谢谢!事实上,我运行的进程比处理器多。
【解决方案2】:

听起来有三种方法可以等待 MPI 消息:

  1. 积极的忙等待。这将尽快将消息发送到您的接收代码中。一些处理器除了检查传入的消息之外什么都不做。如果您将所有处理器都置于这种状态,那么系统的其余部分将会非常缓慢。 MPI 默认使用激进模式。
  2. 降级忙等待。这将在忙等待时让步给其他进程。如果您要求的进程数多于您拥有的处理器数,MPI 将切换到降级模式。您还可以使用 an MCA parameter 强制使用激进或降级模式。
  3. 轮询。即使降级的忙等待仍然是一个忙等待,它会为每个正在等待的进程保持一个处理器固定在 100%。如果您的系统上有其他不想与之竞争的任务,您可以在调用阻塞接收之前通过睡眠调用循环call MPI_Iprobe()。我发现 100 毫秒的睡眠对于我的任务来说已经足够响应了,并且在工作人员空闲时仍然保持 CPU 使用率最低。

我做了一些搜索,发现 a busy wait is what you want 如果您不与其他任务共享您的处理器。

【讨论】:

    猜你喜欢
    • 2018-02-17
    • 1970-01-01
    • 2018-10-22
    • 2015-05-18
    • 2012-01-26
    • 1970-01-01
    • 1970-01-01
    • 2020-05-30
    相关资源
    最近更新 更多