Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "pch.h"
- #include <iostream>
- #include <omp.h>
- #include <ctime>
- #include <math.h>
- int getRandomNumber(long min, long max)
- {
- static const double num = 1.0 / (static_cast<double>(RAND_MAX) + 1.0);
- // равномерно распределяем рандомное число в нашем диапазоне
- return static_cast<long>(rand() * num * (max - min + 1) + min);
- }
- int main()
- {
- setlocale(LC_ALL, "Rus");
- long n = 0;//размерность массива
- int p = omp_get_num_threads(); //колво потоков
- double time, time1, time2, time3;
- double sum1 = 0;
- double sum2 = 0;
- double sum3 = 0;
- double sum = 0, psum = 0;
- std::cout << "Введите n (от 100000 до 1000000) = ";
- while (!(std::cin >> n) || (std::cin.peek() != '\n') || (n < 100000) || (n > 1000000))
- {
- std::cin.clear();
- while (std::cin.get() != '\n');
- std::cout << "Ошибка ввода, повторите попытку!" << std::endl;
- std::cout << "Введите n (от 100000 до 1000000) = ";
- }
- std::cout << "Введите кол-во потоков (по умолчанию " << omp_get_num_threads() << ") = ";
- while (!(std::cin >> p) || (p <= 0))
- {
- std::cin.clear();
- while (std::cin.get() != '\n');
- std::cout << "Ошибка ввода, повторите попытку!" << std::endl;
- std::cout << "Введите кол-во потоков (по умолчанию " << omp_get_num_threads() << ") = ";
- }
- long *arr = new long[n];//создание массива
- omp_set_num_threads(p);//указываем колво потоков
- //Генерация массива
- for (long i = 0; i < n; i++)
- {
- arr[i] = getRandomNumber(100, 10000000);
- }
- //---------------------------------------------
- //Один поток
- time = omp_get_wtime();
- for (long i = 0; i < n; i++)
- {
- sum1 += sqrtl(arr[i]);
- }
- time1 = omp_get_wtime() - time;
- //---------------------------------------------
- //Многопоточное через critical
- time = omp_get_wtime();
- #pragma omp parallel firstprivate(psum) shared(sum) //Директива задает параллельный участок, в котором будет опция firstprivate,
- //которая задает способ инициализации инди-видуальных переменных. И опция shared, которая задает общие переменные.
- {
- psum = 0;
- #pragma omp for//непосредственно само распараллеливание
- for (int i = 0; i < n; i++)
- {
- psum += sqrtl(arr[i]);
- }
- #pragma omp critical//создание критической секции для того чтобы в общую переменную перемножить значения из потоков.
- {
- sum += psum;
- }
- }
- time2 = omp_get_wtime() - time;
- sum2 = sum;
- sum = 0;
- psum = 0;
- //---------------------------------------------
- //Многопоточное через reduction
- time = omp_get_wtime();
- #pragma omp parallel for reduction (+:sum)//Директива задает параллельный участок. Опция reduction (* : r) означает,
- //что после выхода из параллельного участка переменная на главном потоке r будет увеличена на величину произведения значений этой переменной, подсчитанных на каждом из потоков.
- for (int i = 0; i < n; i++)
- {
- sum += sqrtl(arr[i]);
- }
- time3 = omp_get_wtime() - time;
- sum3 = sum;
- //--------------------------------------------
- //Вывод результатов
- std::cout << "-----------------------------------------------------------------" << std::endl;
- std::cout << "Однопоточное выполнение: " << std::endl;
- std::cout << "\tРезультат = " << sum1 << std::endl;
- std::cout << "\tВремя выполнения = " << time1 << " мс" << std::endl;
- std::cout << "Многопоточное выполнение (" << p << " нити), через critical: " << std::endl;
- std::cout << "\tРезультат = " << sum2 << std::endl;
- std::cout << "\tВремя выполнения = " << time2 << " мс" << std::endl;
- std::cout << "Многопоточное выполнение (" << p << " нити), через reduction: " << std::endl;
- std::cout << "\tРезультат = " << sum3 << std::endl;
- std::cout << "\tВремя выполнения = " << time3 << " мс" << std::endl;
- std::cout << "-----------------------------------------------------------------" << std::endl;
- delete[] arr;
- system("pause");
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement