парал прогр / 2020_2021_311_парал_Филатова_Work11
.docxWork 11 Филатова ольга 311
int NProc, ProcId;
double fun(double x, double y, double a1, double b1, double a2, double b2) {
return (exp(sin(PI * x) * cos(PI * y)) + 1) / ((b1 - a1) * (b2 - a2));
}
void firstIntegral(const double a1, const double b1, const double a2, const double b2, const double hx, const double hy, double* res) {
double sum = 0.0; // локальная переменная для подсчета интеграла
double x, y; // координаты точки сетки
int n = (int)((b1 - a1) / hx);
int m = (int)((b2 - a2) / hy);
for (x = a1 + hx / 2; x < b1; x += hx) {
for (int j = ProcId; j < m; j += NProc) {
y = a2 + j * hy + hy / 2.0;
sum += fun(x, y, a1, b1, a2, b2) * hx * hy;
}
}
MPI_Reduce(&sum, res, 1, MPI_LONG_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
}
void secondIntegral(const double a1, const double b1, const double a2, const double b2, const double hx, const double hy, double* res) {
double sum = 0.0; // локальная переменная для подсчета интеграла
for (long double x = a1 + hx / 2; x < b1; x += hx) {
for (long double y = a2 + (ProcId + 1) * hy / 2; y < b2; y += NProc * hy) {
sum += fun(x, y, a1, b1, a2, b2);
}
}
MPI_Reduce(&sum, res, 1, MPI_LONG_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
if (ProcId == 0) {
*res *= hx * hy;
}
}
double experiment(double* res) {
double stime;
double a1 = 0.0; // левая граница интегрирования
double b1 = 16.0; // правая граница интегрирования
double a2 = 0.0; // левая граница интегрирования
double b2 = 16.0; // правая граница интегрирования
double hx = 0.001; // шаг интегрирования по x
double hy = 0.001; // шаг интегрирования по y
if (ProcId == 0) {
stime = MPI_Wtime();
}
firstIntegral(a1, b1, a2, b2, hx, hy, res); // вызов функции интегрирования
//secondIntegral(a1, b1, a2, b2, hx, hy, res); // вызов функции интегрирования
if (ProcId == 0) {
return MPI_Wtime() - stime;
}
}
Версия программы, распараллеленная с помощью MPI, работает значительно быстрее последовательной и параллельной OMP