Зонд, кажется, потребляет процессор

У меня есть программа MPI, состоящая из одного главного процесса, который передает команды группе подчиненных процессов. Получив команду, ведомое устройство просто вызывает для этого system(). Пока ведомые устройства ожидают команды, они потребляют 100% своих соответствующих ЦП. Похоже, что Probe() находится в жестком цикле, но это только предположение. Как вы думаете, что может быть причиной этого, и что я могу сделать, чтобы это исправить?

Вот код подчиненного процесса, ожидающего команды. Одновременный просмотр журнала и команды top позволяет предположить, что, когда ведомые устройства потребляют свои ЦП, они находятся внутри этой функции.

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;
}

person Ben Kovitz    schedule 28.01.2013    source источник
comment
Обратите внимание, что вы должны знать о возможных ошибках сегментации при вызове fork() в системах с интерконнектом OpenFabrics (InfiniBand или iWARP).   -  person Hristo Iliev    schedule 28.01.2013


Ответы (2)


Да; большинство реализаций MPI, ради производительности, заняты ожиданием блокирующих операций. Предполагается, что задание MPI — это единственное, что нас волнует в процессоре, и если задача заблокирована в ожидании связи, лучшее, что можно сделать, — это постоянно опрашивать эту связь, чтобы уменьшить задержку; так что практически нет задержки между получением сообщения и его передачей задаче MPI. Обычно это означает, что ЦП привязан к 100%, даже когда ничего «настоящего» не делается.

Вероятно, это лучшее поведение по умолчанию для большинства пользователей MPI, но это не всегда то, что вам нужно. Обычно реализации MPI позволяют отключить это; с OpenMPI, вы можете отключить это поведение с помощью параметра MCA,

mpirun -np N --mca mpi_yield_when_idle 1 ./a.out
person Jonathan Dursi    schedule 28.01.2013
comment
Спасибо! Действительно, я запускал больше процессов, чем процессоров. - person Ben Kovitz; 31.01.2013

Похоже, есть три способа дождаться сообщения MPI:

  1. Агрессивное занятое ожидание. Это позволит получить сообщение в ваш принимающий код как можно быстрее. Какой-то процессор ничего не делает, кроме проверки входящего сообщения. Если вы поместите все свои процессоры в это состояние, остальная часть вашей системы будет работать очень медленно. MPI по умолчанию использует агрессивный режим.
  2. Ухудшенное занятое ожидание. Это уступит место другим процессам во время ожидания. Если количество запрашиваемых вами процессов превышает количество имеющихся у вас процессоров, MPI переключается в ухудшенный режим. Вы также можете включить агрессивный или ограниченный режим с помощью параметра MCA.
  3. Опрос. Даже ухудшенное ожидание занятости по-прежнему остается ожиданием занятости, и оно будет удерживать один процессор на уровне 100% для каждого ожидающего процесса. Если в вашей системе есть другие задачи, с которыми вы не хотите конкурировать, вы можете вызов MPI_Iprobe() в цикле со спящим вызовом перед вызовом блокирующего приема. Я считаю, что спящий режим в 100 мс достаточно отзывчив для моих задач и по-прежнему сохраняет минимальное использование ЦП, когда рабочий бездействует.

Я провел поиск и обнаружил, что занятое ожидание — это то, что вам нужно. хотите, если вы не используете свои процессоры совместно с другими задачами.

person Don Kirkby    schedule 28.01.2015