2010-01-13 4 views
0

Я хочу использовать MPI (MPICH2) для окон. Я пишу эту команду:MPI Barrier C++

MPI_Barrier(MPI_COMM_WORLD); 

И я ожидаю, что он блокирует все Процессоры, пока все члены группы не назвали это. Но этого не происходит. Добавить схему моего кода:

int a; 
if(myrank == RootProc) 
    a = 4; 
MPI_Barrier(MPI_COMM_WORLD); 
cout << "My Rank = " << myrank << "\ta = " << a << endl; 

(С 2 процессора процессор :) Root (0) действует правильно, но процессор с 1-го ранга не знает переменную a, поэтому отображение -858993460 вместо 4.

Может ли кто-нибудь мне помочь?
С уважением

ответ

6

Вы только назначая a в процессе 0. MPI не разделяет память, так что если вы хотите, чтобы a в процессе 1, чтобы получить значение 4, то необходимо вызвать MPI_Send от процесса 0 и MPI_Recv от процесса 1 .

+0

Спасибо. Это правда, но у меня есть другой вопрос. Поскольку я знаю, что барьер блокирует вызывающего абонента, пока все члены группы его не вызвали, но я протестировал и увидел, что этот процесс 1 передает эту функцию (путем написания предложения, cout), а процесс root (0) - перед барьером. В чем проблема? Спасибо – aryan

+0

Вы не можете доверять порядку выходных операторов из разных процессов. Если вы не уверены, убедитесь, что ваши часы синхронизированы и выведены 'time()' до и после барьера. – eduffy

+0

Не ожидайте, что часы на разных процессорах будут находиться в такой близкой синхронизации, что время, которое они сообщают, позволяет корректно упорядочивать выходные инструкции. MPI_Barrier синхронизирует процессы, а не часы. –

1

Переменная a не инициализирована - возможно, поэтому она отображает это число. В MPI переменная a дублируется между процессами - поэтому для a есть два значения, один из которых неинициализирован. Вы хотите написать:

int a = 4; 
if (myrank == RootProc) 
... 

Или, наоборот, сделать в Root (ID 0) в MPI_send, и MPI_recv в раба (ID 1), так что значение в корне также установлен в ведомом.

Примечание: этот код вызывает небольшую тревогу в моей голове, поэтому мне нужно что-то проверить, и я отредактирую это с дополнительной информацией. До тех пор, хотя, неинициализированное значение, безусловно, является проблемой для вас. Хорошо, я проверил факты - ваш код не был правильно отступом, и я пропустил отсутствующий {}. Теперь барьер выглядит прекрасным, хотя фрагмент, который вы разместили, не делает слишком много, и это не очень хороший пример барьера, потому что подчиненный вводит его напрямую, тогда как корень установит значение переменной в 4, а затем введите его , Чтобы проверить, что это действительно работает, вам, вероятно, нужен какой-то механизм сна в одном из процессов - это даст (надеюсь, что это правильный термин) другой процесс, а также не даст ему напечатать cout до тех пор, пока сон не закончится.

1

Blocking не хватает, вы должны отправить данные на другие процессы (память не используется совместно между процессами).

Для обмена данными по всем процессам использование:

int MPI_Bcast(void* buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm) 

так в вашем случае:

MPI_Bcast(&a, 1, MPI_INT, 0, MPI_COMM_WORLD); 

здесь вы отправляете одно целое число, на который указывает & процесс, форма от 0 до всех остальных. // MPI_Bcast является отправителем для корневого процесса и приемник для некорневых процессов

Вы также можете отправить некоторые данные specyfic процесса путем:

int MPI_Send(void *buf, int count, MPI_Datatype datatype, int dest, 
       int tag, MPI_Comm comm) 

, а затем получить по:

int MPI_Recv(void* buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status *status)