Вычисление определенных интегралов методом прямоугольников с помощью 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.