Могут ли данные быть потеряны в парах MPI_Send / MPI_Recv, если они не синхронизированы правильно?
Позволь мне объяснить. Рассмотрим 4 подчиненных узла 1, 2, 3, 4 и главный узел 0. Теперь, 1, 2, 3, 4, нужно отправить данные на 0. 0 получает эти данные в следующем формате.
for(int proc = 1;proc<procCount;proc++) // for each processor cpu (procCount = 5)
{
for(int p = 0;p<50;p++)
{
std::cout<<proc<<"\tA\t"<<p<<std::endl;
// read in binary datas
int chunkP;
int realP;
real fitnessVal;
real fitnessValB;
real fitnessValC;
int conCount;
real subConCount;
real networkEnergyLoss;
real movementEnergyLoss;
long spikeCount;
MPI_Recv (reinterpret_cast < char *>(&chunkP),
sizeof (chunkP),
MPI_CHAR,proc,MPI_ANY_TAG,MPI_COMM_WORLD,&stat);
MPI_Recv (reinterpret_cast < char *>(&realP),
sizeof (realP),
.
.
.
}
}
Ясно, что порядок, в котором 1, 2, 3 и 4 отправляют данные в 0, не может быть принят (так как все они работают независимо друг от друга - 2 могут отправлять данные раньше 1). Таким образом, предполагая, что 2 отправляет свои данные до 1 (например), цикл приема в 0, показанный выше, не будет инициирован, пока исходный тег 'proc' в команде MPI_Recv не будет сопоставлен с процессором '1', потому что внешний цикл for вызывает этот порядок.
Так что происходит, когда цикл "ждет", пока не поступят данные, поступающие от 1, прежде чем он сможет что-либо делать, даже если уже есть данные, поступающие с 2, 3 и 4. Что происходит с этими данными, поступающими с 2,3 и 4, если он прибывает раньше 1? Может ли это быть "забыто" в том смысле, что как только данные из "1" начинают поступать, а затем proc увеличивается до 2, данных, которые он первоначально пытался получить из 2, просто больше не существует? Если оно "забыто", то все распределенное моделирование просто зависнет, потому что оно никогда не сможет правильно обработать данные определенного подчиненного процесса.
Спасибо, Бен.
1 ответ
Во-первых, вы действительно хотите получить MPI_CHAR
в чанк - int
- не должны ли вы получить MPI_INT
?
Сообщения из рядов 1:4 не будут потеряны - они будут помещены в очередь, пока уровень 0 не решит их получать. Такое поведение предписано стандартом MPI.
Если сообщения достаточно велики, ранги 1:4 могут блокироваться до тех пор, пока они действительно не смогут отправлять свои сообщения на ранг 0 (большинство реализаций MPI имеют ограниченную буферизацию).
Вы также можете рассмотреть вопрос о присвоении ранга 0 MPI_ANY_SOURCE
получить для первого получения, чтобы увидеть, кто готов отправить. Вам нужно будет позаботиться, чтобы убедиться, что последующие поступления публикуются для соответствующего источника - смотрите в MPI_Status
Структура, чтобы увидеть, откуда сообщение было отправлено.