Тест MPI_Barrier C ++ - PullRequest
       36

Тест MPI_Barrier C ++

2 голосов
/ 14 января 2010

Как я могу быть уверен, что MPI_Barrier работает правильно? Какой метод проверки для этого?
Спасибо

Ответы [ 3 ]

4 голосов
/ 14 января 2010

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

Не думаю, что ответ @ Neeraj будет вести себя так. Если барьер работает правильно, все процессы будут записывать свои первые выходные строки до того, как кто-либо из них записывает вторую выходную строку. Однако возможно, что это произойдет даже в отсутствие барьера (или там, где барьер полностью разрушился, если вы хотите думать об этом таким образом). Мое утверждение не зависит от очень короткого времени сна, которое он предлагает (5ms rank). Даже если вы предполагаете, что процессы ждут (5s rank), возможно, что операторы будут появляться в наложенном барьером порядке в отсутствие барьера. Маловероятно, я даю вам, но не невозможно, особенно когда вам нужно рассмотреть, как o / s буферизует множественные записи в stdout - вы можете на самом деле тестировать этот процесс, а не барьер. О вы плачете даже самые неточные часы компьютера приведут к тому, что процесс 1 будет ждать меньше времени, чем процесс 2, чтобы показать правильную работу барьера. Нет, если o / s преимущественно захватывает Процессор 1 (на котором процесс 1 пытается работать) в течение 10 секунд не работает.

Зависимость от встроенных часов для синхронизации фактически делает программу менее детерминированной. Все процессоры имеют свои собственные часы, и аппаратное обеспечение не дает никаких гарантий, что все они будут работать с одинаковой частотой или с одинаковой длиной такта.

Также этот тест не позволяет адекватно исследовать все режимы отказа барьера. В лучшем случае это только исследует полный отказ; Что если реализация на самом деле является барьером от утечек, так что иногда процесс проходит до того, как последний процесс достиг барьера? Одиночные ошибки невероятно распространены в программах. Или, возможно, барьерный код был написан 3 года назад, и у него достаточно памяти, чтобы записать, например, 2 ^ 12 == 4096 процессов, и вы установили его на совершенно новую машину с 2 ^ 18 процессорами; барьер больше плотины, чем плотины.

До сих пор я не задумывался об этом глубоко, я никогда не подозревал, что у любой из реализаций MPI, которые я использовал, были дефектные барьеры, поэтому у меня нет хорошего предложения о том, как тщательно протестировать барьер. Я был бы склонен использовать параллельный отладчик и проверять выполнение программы через барьер, но это не дает гарантии правильного поведения.

Хотя это интересный вопрос.

0 голосов
/ 09 июня 2011

Аллен Дауни в своей книге Маленькая книга семафоров говорит следующее (об алгоритме многоразового барьера, который он представляет):

К сожалению, это решение типичный для большинства нетривиальных код синхронизации: это сложно чтобы быть уверенным, что решение является правильным. Часто есть тонкий способ, которым конкретный путь через программу может вызвать ошибку.

Что еще хуже, тестирование реализация решения не большая помощь Ошибка может произойти очень редко, потому что конкретный путь что вызывает это может потребовать потрясающе неудачное сочетание обстоятельства. Такие ошибки почти невозможно воспроизвести и отладить с помощью обычные средства.

Единственная альтернатива - изучить кодировать тщательно и «доказать», что это правильный. Я поставил «доказать» в цитате оценки, потому что я не имею в виду, обязательно, что вы должны написать формальное доказательство (хотя есть фанатики, которые поощряют такое безумие).

0 голосов
/ 14 января 2010

#include <mpi.h>

int main (int argc , char *argv[])
{
  int rank;

  MPI_Init (&argc, &argv);      /* starts MPI */
  MPI_Comm_rank (MPI_COMM_WORLD, &rank);        /* get current process id */

  sleep(5*rank); // make sure each process waits for different amount of time
  std::cout << "Synchronization point for:" << rank << std::endl ;
  MPI_Barrier(MPI_COMM_WORLD) ;
  std::cout << "After Synchronization, id:" << rank << std::endl ;

  MPI_Finalize();
  return 0;
}
...