Потерянные сообщения между процессами PVM?
Я пытаюсь распараллелить алгоритм, используя PVM для университетского задания. Я отсортировал алгоритм, но распараллеливание только почти работает - процесс периодически прерывается без видимой причины. Я не вижу никакой картины, прогон с теми же параметрами может сработать 10 раз, а затем просто застрянет на следующем усилии...
Ни один из pvm
функции (в главном или любом дочернем процессе) возвращают любые коды ошибок, дочерние элементы, кажется, завершаются успешно, ошибки не достигают консоли. Это действительно похоже на то, что хозяин не получает все сообщения от детей - но только изредка.
Как ни странно, я не думаю, что это просто пропуск сообщения - у меня еще не было результата, отсутствующего у потомка, который затем успешно отправил полный сигнал (то есть у меня не было завершения выполнения пробега и (неожиданный результат) - это как если бы ребенок просто отключился, и все сообщения с определенной точки перестали поступать.
Пакетирование результатов и отправка меньших, но более крупных сообщений, кажется, повышает надежность, по крайней мере кажется, что они торчат реже - у меня нет точных цифр, чтобы поддержать это...
Это нормально, распространено или ожидается, что PVM потеряет сообщения, отправленные через pvm_send
а это друзья? Обратите внимание, что ошибка возникает, если все процессы выполняются на одном или нескольких хостах.
Я делаю что-то неправильно? Что я могу сделать, чтобы предотвратить это?
Обновить
Я воспроизвел ошибку в очень простом тестовом примере, код которого приведен ниже. Он просто порождает четырех дочерних элементов, отправляет каждому по одному числу, каждый дочерний элемент умножает полученное число на пять и отправляет его обратно. Это работает почти все время, но иногда мы замираем, когда распечатываются только три числа, при этом отсутствует результат одного ребенка (и он говорит, что ребенок будет заполнен).
Мастер:
int main()
{
pvm_start_pvmd( 0 , NULL , 0 );
int taskIDs[global::taskCount];
pvm_spawn( "/path/to/pvmtest/child" , NULL , 0 , NULL , global::taskCount , taskIDs );
int numbers[constant::taskCount] = { 5 , 10 , 15 , 20 };
for( int i=0 ; i<constant::taskCount ; ++i )
{
pvm_initsend( 0 );
pvm_pkint( &numbers[i] , 1 , 1 );
pvm_send( taskIDs[i] , 0 );
}
int received;
for( int i=0 ; i<global::taskCount ; ++i )
{
pvm_recv( -1 , -1 );
pvm_upkint( &received , 1 , 1 );
std::cout << recieved << std::endl;
}
pvm_halt();
}
Ребенок:
int main()
{
int number;
pvm_recv( -1 , -1 );
pvm_upkint( &number , 1 , 1 );
number *= 10;
pvm_initsend( 0 );
pvm_pkint( &number , 1 , 1 );
pvm_send( pvm_parent() , 0 );
}
1 ответ
Не совсем ответ, но две вещи изменились вместе, и проблема, похоже, утихла:
я добавил
pvm_exit()
вызов конца ведомого двоичного файла, что, очевидно, лучше всего сделать.Конфигурация PVM в кластере изменилась... каким-то образом... У меня нет никаких подробностей, но несколько узлов ранее не могли участвовать в операциях PVM и теперь могут. Другие вещи, возможно, также изменились.
Я подозреваю, что что-то в течение второго изменения также случилось, чтобы исправить мою проблему.