Вычисление определенных интегралов методом прямоугольников с помощью MPI
Курсовой проект - Компьютеры, программирование
Другие курсовые по предмету Компьютеры, программирование
ем интервале [X (1), X (N)]. Процессорам 1. (N-1) ставятся в соответствие подинтервалы [X (I), X (I+1)]. Затем вычисляется интеграл Q (I) методом прямоугольников для каждого отрезка интервала функции F (x).
Процессор 0 передает процессору I границы отведенного ему подинтервала. Процессор I возвращает процессору 0 вычисленное значение Q (i).
Листинг программы на языке С.
# include
# include
# include
# include
# include "mpi. h"main (int argc, char *argv []);
double f (double x);timestamp (void);
/******************************************************************************/main (int argc, char *argv [])
{end_time;h;i;ierr;m;master = 0;n;process;process_id;process_num;
double q_global;q_local;
int received;source;start_time;_Status status;tag;
int target;x;xb [2];x_max = 3.0;x_min = 0.0;= MPI_Init (&argc, &argv);
/*
Определим номер текущего процессора.
*/= MPI_Comm_rank (MPI_COMM_WORLD, &process_id);
/*
Получение количества процессоров
*/= MPI_Comm_size (MPI_COMM_WORLD, &process_num);
/*
Проверка количества доступных процессоров
*/
if (process_id == master)
{
timestamp ();
printf ("\n");
printf ("Главный процессор: \n");
printf ("\n");
printf (" Программа для вычиления определенных интегралов,\n");
printf (" Назначение подинтервалов процессорам. \n");
printf ("\n");
printf (" количество процессоров %d\n", process_num);
start_time = MPI_Wtime ();(process_num <= 1)
{
printf ("\n");
printf ("главный процессор: \n");
printf (" Нужно как минимум 2 процессора! \n");= MPI_Finalize ();("\n");
printf ("Главный процессор: \n");
printf (" Ненормальное завершение работы. \n");
exit (1);
}
}
printf ("\n");
/*
рассчет точек концов подинтервалов и их рассылка по процессорам - адресатам.
*/(process_id == master)
{(process = 1; process <= process_num-1; process++)
{[0] = ( (double) (process_num - process) * x_min
+ (double) (process - 1) * x_max)
/ (double) (process_num - 1);[1] = ( (double) (process_num - process - 1) * x_min
+ (double) (process) * x_max)
/ (double) (process_num - 1);= process; = 1;
printf ("Точки интервалов %f! \n", xb [0]);= MPI_Send (xb, 2, MPI_DOUBLE, target, tag, MPI_COMM_WORLD);
}
}
{= master;= 1;= MPI_Recv (xb, 2, MPI_DOUBLE, source, tag, MPI_COMM_WORLD, &status);
}
/*
дождемся, когда все процессоры получать свои назначения.
*/= MPI_Barrier (MPI_COMM_WORLD);
if (process_id == master)
{("\n"); ("Главный процессор: \n");
printf (" Подинтервалы назначены. \n");
}
/*
каждому процессору нужно передать количество точек
для вычислений по широковещательной рассылке.
*/
m = 100;
source = master;
ierr = MPI_Bcast (&m, 1, MPI_INT, source, MPI_COMM_WORLD);
/*
каждый процессор выполняет вычисления над своим интервалом и передает результат
процессору 0.
*/(process_id! = master)
{
q_local = 0.0;
printf ("Процессор %d активен! \n", process_id);(i = 1; i <= m; i++)
{= ( (double) (2 * m - 2 * i + 1) * xb [0]
+ (double) (2 * i - 1) * xb [1])
/ (double) (2 * m);_local = q_local + f (x);
}_local = q_local * (xb [1] - xb [0]) / (double) (m);= master;= 2;= MPI_Send (&q_local, 1, MPI_DOUBLE, target, tag, MPI_COMM_WORLD);
}
/*
процессор 0 ждет N-1 промежуточного результата.
*/
{= 0;_global = 0.0;(received < process_num - 1)
{= MPI_ANY_SOURCE;= 2;= MPI_Recv (&q_local, 1, MPI_DOUBLE, source, tag, MPI_COMM_WORLD,
&status);_global = q_global + q_local; = received + 1;
}
}
/*
главный процессор выдает результат
*/(process_id == master)
{("\n");("Главный процессор: \n");(" Интеграл ф-ии F (x) = %f\n", q_global);(" Ошибка вычислений %f\n", q_global - 0.624);_time = MPI_Wtime ();("\n"); (" Время, затраченное на вычисления = %f\n",
end_time - start_time);
}
/*MPI.
*/= MPI_Finalize ();
/*.
*/(process_id == master)
{
printf ("\n");
printf ("Главный процессор: \n");
printf (" Нормальное завершение вычислений. \n");
printf ("\n");();
}0;
}
/************************************************************/f (double x)
{value;= 2.0*cos (x) / (2.0 + x * x);value;
}
/************************************************************/timestamp (void)
{
# define TIME_SIZE 40char time_buffer [TIME_SIZE];struct tm *tm;_t now;= time (NULL);= localtime (&now);(time_buffer, TIME_SIZE, "%d %B %Y %I: %M: %S %p", tm);("%s\n", time_buffer);;
# undef TIME_SIZE
}
Литература
1..">
2.-MPI.">
.Богачев К.Ю. Основы параллельного программирования. - М.: БИНОМ. Лаборатория знаний, 2003.
.-MPI."> - часто задаваемые вопросы по MPI.