我有一个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;
}
答案 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消息:
MPI_Iprobe()
。我发现100毫秒的睡眠响应能够完成我的任务,并且当工作人员闲置时仍能保持最低的CPU使用率。如果您没有与其他任务共享处理器,我进行了一些搜索并发现a busy wait is what you want。