Состояние гонки с MPI - PullRequest
       20

Состояние гонки с MPI

2 голосов
/ 21 октября 2011

Я пытаюсь реализовать Турнирный барьер, используя MPI. Вот код, который я написал. Я пишу только фазу прибытия и фазы пробуждения

//Arrival phase
while(1)
{
    if((!strcmp(round[my_id][round_num].role,"winner"))||(!strcmp(round[my_id][round_num].role,"champion")))
    {
       printf("%d is the winner of round %d\n",my_id,round_num);
       MPI_Recv(&reach_msg, sizeof(reach_msg), MPI_BYTE, round[my_id][round_num].opponent, tag, MPI_COMM_WORLD, &status);
       printf("%d received: %s\n",my_id,reach_msg);
    }

    else if(!strcmp(round[my_id][round_num].role,"loser"))
    {
       printf("%d is the loser of round %d\n",my_id,round_num);
       sprintf(reach_msg,"%d arrived at the barrier",my_id);
       MPI_Send(reach_msg,strlen(reach_msg+1),MPI_BYTE,round[my_id][round_num].opponent,tag,MPI_COMM_WORLD);
       MPI_Recv(wakeup_msg,sizeof(wakeup_msg),MPI_BYTE,round[my_id][round_num].opponent,tag,MPI_COMM_WORLD,&status);
       printf("%d received: %s\n",my_id,wakeup_msg);
    }

if(round_num==num_rounds)
       break;
    else
       round_num++;
}

printf("%d is out of arrival tree\n",my_id);

//wakeup tree
      while(1)
     {
       printf("%d prints: round num is: %d\n",my_id,round_num);
       if(round_num==0)
            break;
       sprintf(wakeup_msg,"wakeup msg from %d of %d",my_id,P);

       if((!strcmp(round[my_id][round_num].role,"winner"))||(!strcmp(round[my_id][round_num].role,"champion")))
       MPI_Send(wakeup_msg,strlen(wakeup_msg+1),MPI_BYTE,round[my_id][round_num].opponent,tag,MPI_COMM_WORLD);
       round_num--;
      }

    MPI_Finalize();
    return 0;
   }

Я не понимаю, почему возникают расы. Я считаю, что MPI_Send и MPI_Recv являются блокирующими функциями. Но иногда это не так

РЕДАКТИРОВАТЬ : Вот пример выходных данных, где происходит состояние гонки. Как видно, 0 получило сообщение («1 прибыл на барьер») от 1 еще до того, как 1 отправил сообщение.

0 - победитель раунда 1

0 получено: 1 прибыл в барри

0 - победитель раунда 2

1 - проигравший в раунде 1

1 отправка достигает сообщения MSG

2 - победитель раунда 1

2 получено: 3 прибыли в барри

2 - проигравший в раунде 2

2 отправка достичь сообщения MSG

3 - проигравший в раунде 1

3 отправка достигает сообщения MSG

0 получено: 2 прибыли в барри

0 отправка сообщения пробуждения

0 отправка сообщения пробуждения

1 получено: сообщение о пробуждении от 0 с меткой в ​​раунде 1

2 получено: сообщение о пробуждении от 0 с меткой в ​​раунде 2

2 отправка сообщения пробуждения

3 получено: сообщение о пробуждении от 2 с меткой в ​​раунде 1

Ответы [ 3 ]

2 голосов
/ 21 октября 2011

По моему опыту у вас, скорее всего, есть проблема наблюдения, а не вашего основного алгоритма. Обычно printf s в такой настройке просто выходят из строя. Вы должны были бы

  • вставьте метки времени в ваш вывод
  • запись в разные файлы, по одному на каждый процесс MPI
  • объедините их вместе, отсортировав по вашей отметке времени
1 голос
/ 22 октября 2011

Для отладки программ mpi операторы print обычно не очень удачное решение.Поскольку распечатки отчетов должны быть отправлены на консоль из разных узлов сети и кэшированы ранее.

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

0 голосов
/ 21 октября 2011

Я не уверен, что полностью понимаю вашу проблему ... добавление вывода кода в ваш вопрос может помочь.

Что я могу сказать точно, так это то, что MPI_Send и MPI_Recv определенно блокируют функции.Вы пытались использовать неблокирующие функции (например, MPI_Isend и MPI_Irecv)?Если да, это решило вашу проблему?

...