2015-03-12 2 views
2

Я пытаюсь реализовать рабочий пул здесь. Я должен отправить 100 различных чисел в числа в подчиненные процессы. Каждый подчиненный процесс затем возвращает что-то к мастер-процессу, а другое подчинение подчиняется главному. Это продолжается до тех пор, пока все 100 итераций не закончатся.MPI_Send и MPI_Recv не соответствуют C

Моя программа застряла в бесконечном цикле, который, по моему мнению, обусловлен неправильным отображением MPI_Send и MPI_Recv. Я не могу понять, что я делаю неправильно. Я потратил немало часов на изучение этого, но безрезультатно. Я новичок в MPI и программировании в целом. Код указан ниже:

if(rank == 0) { 
     int i,iteration = 0, a=0,inside=0,temp=0; 
     for(i = 1; i < slaves; i++) { 
     MPI_Send(&iteration,1,MPI_INT,i,0,MPI_COMM_WORLD); 
     MPI_Send(&a,1,MPI_INT,i,1,MPI_COMM_WORLD); 
     iteration++; 
    } 
    while(iteration < 100+slaves){ 
     MPI_Recv(&temp,1,MPI_INT,MPI_ANY_SOURCE,0, MPI_COMM_WORLD, &status); 
     if(iteration < 100) { 
      MPI_Send(&iteration,1,MPI_INT,status.MPI_SOURCE,0,MPI_COMM_WORLD); 
      MPI_Send(&a,1,MPI_INT,status.MPI_SOURCE,1,MPI_COMM_WORLD); 
     } 
     iteration++; 
     inside = inside + temp; 
    } 
} 
else { 
    int iteration=0,count=0; 
    if(iteration < 100) { 
     MPI_Recv(&iteration,1,MPI_INT,0,0,MPI_COMM_WORLD,&status); 
     MPI_Recv(&count,1,MPI_INT,0,1,MPI_COMM_WORLD,&status); 
     MPI_Send(&count,1,MPI_INT,0,0,MPI_COMM_WORLD); 
    } 
} 
+0

Почему цикл начинается от 1, а не от 0: 'for (i = 1; i

+0

@ AntoJurković Поскольку мастер (ранг = 0) должен только отправлять данные подчиненным (ранг> 0). – Sohi

ответ

3

Вам также необходимо зациклиться на рядах ваших рабов. Как она стоит сейчас, вы посылаете iteration и a от ведущего к ведомому, послать count назад от ведомого к ведущему, а потом мастер пытается отправить iteration и a изнутри while цикла, в то время как рабы счастливо вышли из else блокировали и продолжали свой веселый путь. Либо избавитесь от цикла while в основном процессе, чтобы он не отправлял вещи, которые ведомые устройства никогда не получат, или не добавьте их в подчиненные процессы, чтобы они правильно получали эти данные.

2

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

Еще один важный момент, чтобы понять, как работает блокировка/неблокирующая связь в MPI. Здесь мы используем блокирующую связь (MPI_Send() и MPI_Recv()). Это означает, что процесс остановится при вызове функции, например MPI_Recv(), и дождитесь, пока партнер по связям достигнет своего «аналога» (MPI_Send(), чтобы отправить что-то мне).

Тот факт, что ваша программа застревает, является хорошим показателем того, что не имеет одинакового количества MPI_Send() и MPI_Recv() звонков: где-то процесс по-прежнему ожидает получения сообщения/может отправить сообщение.

Для примера, я бы попытаться сделать что-то вроде этого:

while(iterations < 100){ 
    // in general every process has to do something for 100 times, 
    // but we have to have to distinguish between master and slaves. 

    if(mpi_rank == 0){ 
    // The master process... 
    for(int slave_rank = 1; slave_rank < mpi_size; slave_rank++){ 
     // ... has to send, receive and send once again something to/from every(!) slave, ... 
     MPI_Send([one int to slave_rank]); 
     MPI_Recv([one int from slave_rank]); 
     MPI_Send([another int to slave_rank]); 
    } 
    } 
    else{ 
    //... while the slaves just have to receive, send and receive again from/to one process (the master) 
    MPI_Recv([one int from master]); 
    MPI_Send([one int to master]); 
    MPI_Recv([another int from master]); 
    } 
    iterations++; 
} 

Ваша задача звучит так: Master посылает Int к подчиненному # 1, # 2, # 3 ....., то он получает от # 1, № 2, № 3 ...., затем он отправляет другой int на # 1, # 2, # 3. Вероятно, вы узнаете, что вам нужно три раза перебирать все рабские ряды.

Это решение отличается (результат тот же, хотя), но короче: Мастер отправляет int в подчиненный # 1, затем получает int от ведомого # 1, а затем отправляет другой int в подчиненный # 1. Затем повторите одно и то же для slave # 2, # 3, # 4 .... Таким образом, нам просто нужно перебрать все рабские ряды всего за один раз.

Смежные вопросы