Вариант параллелизации этой программы сводится к тому, чтобы просто разделить интервал между процессами, чтобы каждый процесс оценил интеграл на своем подинтервале. Для оценки величины полного интеграла локальные значения всех процессов суммируются.
Пусть программа содержит процессов и трапеций, где является кратным . Тогда первый процесс вычисляет область первых трапеций, второй - область следующих и т.д. Тогда процесс будет оценивать интеграл по интервалу
Каждый процесс должен обладать следующей информацией:
Подведение итогов индивидуальных вычислений процессов состоит в том, чтобы каждый процесс посылал свое локальное значение в процесс 0, а процесс 0 производил заключительное суммирование. Новый вариант программы:
#include ''mpi.h''
float f(float x) {
float return_val;
/* Вычисляет f(x).
Возвращает результат в return_val. */
. . .
return return_val;
}
float Trap(float local_a, float local_b, int local_n,
float h) {
float integral; /* Результат вычислений */
float x;
int i;
integral = (f(local_a) + f(local_b))/2.0;
x = local_a;
for (i = 1; i <= local-n-1; i++) {
x += h;
integral += f(x);
}
integral *= h;
return integral;
} /* Trap */
main(int argc, char** argv) {
int my_rank; /* Ранг процесса */
int p; /* Количество процессов */
float a = 0.0; /* Левая граница */
float b = 1.0; /* Правая граница */
int n = 1024; /* Количество трапеций */
float h; /* Ширина трапеции */
float local_a; /* Левая граница для процесса */
float local_b; /* Правая граница для процесса */
int local_n; /* Количество вычисляемых трапеций */
float integral; /* Значение интеграла по интервалу */
float total; /* Общий интеграл */
int source; /* Процесс, посылающий интеграл */
int dest = 0; /* Пункт назначения процесс 0 */
int tag = 50;
MPI_Status status;
MPI_Init(&argc, &argv);
/* Определить ранг процесса */
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
/* Определить количество процессов */
MPI_Comm_size(MPI_COMM_WORLD, &p);
h = (b-a)/n; /* h одинаково для всех процессов */
local_n = n/p; /* Получить количество трапеций */
/* Вычислить границы интервала и частный интеграл*/
local_a = a + my_rank*local_n*h;
local_b = local_a + local_n*h;
integral = Trap(local_a, local_b, local_n, h);
/* Суммировать все интегралы */
if (my_rank == 0) {
total = integral;
for (source = 1; source < p; source++) {
MPI_Recv(&integral, 1, MPI_FLOAT,
source, tag, MPI_COMM_WORLD, &status);
total += integral;
}
} else {
MPI_Send(&integral, 1, MPI_FLOAT, dest,
tag, MPI_COMM_WORLD);
}
/* Вывод результата */
if (my_rank == 0) {
printf(''C n = %d трапециями, оценка\n'', n);
printf(''интеграла от %f до %f = %f`\n'',
a, b, total);
}
/* Завершить приложение MPI */
MPI_Finalize();
} /* main */