парал прогр / 2020_2021_311_parallel_kochemazov_work01
.docxОтчет по Work1 Кочемазов Василий 311гр
Соберите получившийся код в режиме Debug и запустите его на выполнение.
Сравните результат вычисления с точным значением интеграла ∫ 𝑠𝑖𝑛𝑥𝑑𝑥 𝜋 0 = 2.0.
Полученный результат 1.9999999 очень близок к 2.0
Подберите шаг интегрирования ℎ, чтобы получить значение интеграла с большим приближением.
При h=0.0001 значение интеграла становится равным 2.0
Соберите получившийся код в режиме Release и запустите его на выполнение.
Сравните время выполнения алгоритма численного интегрирования с использованием разных режимов.
Во втором случае время выполнения заметно уменьшилось
Соберите проект 01_omp и запустите на исполнение.
Убедитесь, что на многоядерной/многопроцессорной системе результат работы функции подсчета интеграла совпадает с последовательным, а при удалении параметров private и reduction из директивы omp for существенно отличается от последовательного и, кроме того, меняется от запуска к запуску. Объясните, почему это происходит?
Эти параметры нужны для правильной работы параллельных потоков. Т.е. цикл теперь выполняется не последовательно, а параллельно, и если эти параметры не использовать, то в память хаотично будет записываться результат, и его конечное значение будет неправильным. Вместо параметра private, можно просто сделать x локальной переменной внутри цикла. А параметр reduction помогает подсчитать сумму, после выполнения всех потоков.
Сравните время численного интегрирования для последовательной и параллельной реализации. Какое ускорение выполнения программы предоставляет переход к многопоточной версии?
С помощью #pragma omp parallel осуществляется переход к многопоточной версии. К сожалению, время выполнения данной программы очень мало и не удается отследить разницу между последовательной и многопоточной версией, но очевидно, что многопоточная версия работает быстрее.
Реализуйте параллельные алгоритмы, использующие метод прямоугольников и формулу Симпсона для подсчета интегралов.
Метод прямоугольников:
…
double a = -1.0; // левая граница интегрирования
double b = 1000000; // правая граница интегрирования
…
void integral(const double a, const double b,
const double h, double *res)
{
int i, n;
double sum; // локальная переменная для подсчета интеграла
double x; // координата точки сетки
n = (int)((b - a) / h); // количество точек сетки интегрирования
sum = 0.0;
#pragma omp parallel for private(x) reduction(+: sum)
for (i = -1; i < n; i++)
{
x = a + i * h + h / 2.0;
sum += 1/(x*x + 4*x + 5) * h;
}
*res = sum;
}
С помощью формулы Симпсона:
double f(double x)
{
return 1 / (x*x + 4 * x + 5);
}
void integral(const double a, const double b,
double h, double *res)
{
int i, n;
double sum_1; // локальная переменная для подсчета певрой суммы
double sum_2; // локальная переменная для подсчета второй суммы
n = (int)((b - a) / h); // количество точек сетки интегрирования
h = (b - a) / (2 * n);
sum_1 = 0.0;
sum_2 = 0.0;
#pragma omp parallel for reduction(+: sum_1)
for (i = 1; i <= n; i++)
{
sum_1 += f(a + (2 * i - 1)*h);
}
#pragma omp parallel for reduction(+: sum_2)
for (i = 1; i < n; i++)
{
sum_2 += f(a + 2 * i * h);
}
*res = h / 3 * (f(a) + f(b) + 4 * sum_1 + 2 * sum_2);
}