Ответ 1
Посмотрите этот ответ.
Рассказ: MPI_Init
и MPI_Finalize
не отмечают начало и конец параллельной обработки. Процессы MPI выполняются параллельно.
Это довольно простой вопрос с MPI, но я не могу обернуть его вокруг. У меня есть основная функция, которая вызывает другую функцию, использующую MPI. Я хочу, чтобы основная функция выполнялась в последовательном порядке, а другая функция выполнялась параллельно. Мой код выглядит следующим образом:
int main (int argc, char *argv[])
{
//some serial code goes here
parallel_function(arg1, arg2);
//some more serial code goes here
}
void parallel_function(int arg1, int arg2)
{
//init MPI and do some stuff in parallel
MPI_Init(NULL, NULL);
MPI_Comm_size(MPI_COMM_WORLD, &p);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
//now do some parallel stuff
//....
//finalize to end MPI??
MPI_Finalize();
}
Мой код работает нормально и получает ожидаемый результат, но проблема в том, что основная функция также запускается в отдельных процессах, поэтому серийный код выполняется более одного раза. Я не знаю, как это работает несколько раз, потому что я еще не назвал MPI_Init еще (если я печатаю в main, прежде чем я вызову функцию parallel_function, я вижу несколько printf)
Как я могу остановить свою программу, работающую параллельно после того, как я закончил?
Спасибо за любые ответы!
Посмотрите этот ответ.
Рассказ: MPI_Init
и MPI_Finalize
не отмечают начало и конец параллельной обработки. Процессы MPI выполняются параллельно.
@suszterpatt корректно заявляет, что "процессы MPI выполняются параллельно во всей полноте". Когда вы запускаете параллельную программу, используя, например, mpirun
или mpiexec
, это запустит количество запрошенных процессов (с флагом -n
), и каждый процесс начнет выполнение в начале main
. Итак, в вашем примере кода
int main (int argc, char *argv[])
{
//some serial code goes here
parallel_function(arg1, arg2);
//some more serial code goes here
}
каждый процесс будет выполнять части //some serial code goes here
и //some more serial code goes here
(и, конечно, все они вызовут parallel_function
). Существует не один мастер-процесс, который вызывает parallel_function
, а затем генерирует другие процессы после вызова MPI_Init
.
Как правило, лучше избегать делать то, что вы делаете: MPI_Init
должен быть одним из первых вызовов функций в вашей программе (в идеале это должен быть первый). В частности, обратите внимание на следующее (из здесь):
В стандарте MPI не указано, что может сделать программа до MPI_INIT или после MPI_FINALIZE. В реализации MPICH вы должны сделать как можно меньше. В частности, избегайте всего, что изменяет внешнее состояние программы, например, открытие файлов, чтение стандартного ввода или запись на стандартный вывод.
Несоблюдение этого может привести к некоторым неприятным ошибкам.
Лучше переписать код на что-то вроде следующего:
int main (int argc, char *argv[])
{
// Initialise MPI
MPI_Init(NULL, NULL);
MPI_Comm_size(MPI_COMM_WORLD, &p);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
// Serial part: executed only by process with rank 0
if (my_rank==0)
{
// Some serial code goes here
}
// Parallel part: executed by all processes.
// Serial part: executed only by process with rank 0
if (my_rank==0)
{
// Some more serial code goes here
}
// Finalize MPI
MPI_Finalize();
return 0;
}
Примечание. Я не программист на С, поэтому используйте приведенный выше код с осторожностью. Кроме того, не следует main
всегда возвращать что-то, особенно если оно определено как int main()
?