探针似乎消耗了CPU

时间:2013-01-28 11:09:34

标签: mpi openmpi

我有一个MPI程序,它由一个主进程组成,可以将命令交给一堆从进程。收到命令后,slave只需调用system()来执行此操作。当奴隶正在等待命令时,他们正在消耗100%的各自CPU。似乎Probe()坐在一个紧凑的循环中,但这只是猜测。您认为可能导致这种情况,我该怎么做才能解决这个问题?

这是从属进程中等待命令的代码。同时观察日志和 top 命令表明,当奴隶使用他们的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;
}

2 个答案:

答案 0 :(得分:14)

是;大多数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

答案 1 :(得分:3)

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

  1. 激进的忙碌等待。这将尽快将消息发送到您的接收代码中。有些处理器除了检查传入消息外什么都不做。如果您将所有处理器置于此状态,则系统的其余部分将非常慢。 MPI默认使用主动模式。
  2. 沮丧的忙碌等待。这将在忙碌的等待中产生其他进程。如果您要求的进程数超过您拥有的进程数,MPI将切换到降级模式。您还可以使用an MCA parameter强制攻击性或降级模式。
  3. 轮询。即使是退化的繁忙等待仍然是一个忙碌的等待,并且它将使一个处理器与正在等待的每个进程保持100%挂钩。如果您的系统上还有其他不想与之竞争的任务,则可以在调用阻塞接收之前在具有睡眠呼叫的循环中call MPI_Iprobe()。我发现100毫秒的睡眠响应能够完成我的任务,并且当工作人员闲置时仍能保持最低的CPU使用率。
  4. 如果您没有与其他任务共享处理器,我进行了一些搜索并发现a busy wait is what you want