Advertisement
Guest User

Untitled

a guest
May 24th, 2019
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.70 KB | None | 0 0
  1. #include "pch.h"
  2. #include <iostream>
  3. #include <omp.h>
  4. #include <ctime>
  5. #include <math.h>
  6.  
  7. int getRandomNumber(long min, long max)
  8. {
  9.     static const double num = 1.0 / (static_cast<double>(RAND_MAX) + 1.0);
  10.     // равномерно распределяем рандомное число в нашем диапазоне
  11.     return static_cast<long>(rand() * num * (max - min + 1) + min);
  12. }
  13. int main()
  14. {
  15.     setlocale(LC_ALL, "Rus");
  16.  
  17.     long n = 0;//размерность массива
  18.     int p = omp_get_num_threads();  //колво потоков
  19.     double time, time1, time2, time3;
  20.     double sum1 = 0;
  21.     double sum2 = 0;
  22.     double sum3 = 0;
  23.     double sum = 0, psum = 0;
  24.  
  25.     std::cout << "Введите n (от 100000 до 1000000) = ";
  26.     while (!(std::cin >> n) || (std::cin.peek() != '\n') || (n < 100000) || (n > 1000000))
  27.     {
  28.         std::cin.clear();
  29.         while (std::cin.get() != '\n');
  30.         std::cout << "Ошибка ввода, повторите попытку!" << std::endl;
  31.         std::cout << "Введите n (от 100000 до 1000000) = ";
  32.     }
  33.  
  34.  
  35.  
  36.     std::cout << "Введите кол-во потоков (по умолчанию " << omp_get_num_threads() << ") = ";
  37.     while (!(std::cin >> p) || (p <= 0))
  38.     {
  39.         std::cin.clear();
  40.         while (std::cin.get() != '\n');
  41.         std::cout << "Ошибка ввода, повторите попытку!" << std::endl;
  42.         std::cout << "Введите кол-во потоков (по умолчанию " << omp_get_num_threads() << ") = ";
  43.     }
  44.     long *arr = new long[n];//создание массива
  45.     omp_set_num_threads(p);//указываем колво потоков
  46.  
  47.     //Генерация массива
  48.     for (long i = 0; i < n; i++)
  49.     {
  50.         arr[i] = getRandomNumber(100, 10000000);
  51.     }
  52.     //---------------------------------------------
  53.         //Один поток
  54.     time = omp_get_wtime();
  55.     for (long i = 0; i < n; i++)
  56.     {
  57.         sum1 += sqrtl(arr[i]);
  58.     }
  59.     time1 = omp_get_wtime() - time;
  60.     //---------------------------------------------
  61.         //Многопоточное через critical
  62.     time = omp_get_wtime();
  63. #pragma omp parallel firstprivate(psum) shared(sum) //Директива задает параллельный участок, в котором будет опция firstprivate,
  64.     //которая задает способ инициализации инди-видуальных переменных. И опция shared, которая задает общие переменные.
  65.     {
  66.         psum = 0;
  67. #pragma omp for//непосредственно само распараллеливание
  68.  
  69.         for (int i = 0; i < n; i++)
  70.         {
  71.             psum += sqrtl(arr[i]);
  72.         }
  73.  
  74. #pragma omp critical//создание критической секции для того чтобы в общую переменную перемножить значения из потоков.
  75.  
  76.         {
  77.             sum += psum;
  78.         }
  79.     }
  80.     time2 = omp_get_wtime() - time;
  81.     sum2 = sum;
  82.     sum = 0;
  83.     psum = 0;
  84.     //---------------------------------------------
  85.         //Многопоточное через reduction
  86.     time = omp_get_wtime();
  87. #pragma omp parallel for reduction (+:sum)//Директива задает параллельный участок. Опция reduction (* : r) означает,
  88.     //что после выхода из параллельного участка переменная на главном потоке r будет увеличена на величину произведения значений этой переменной, подсчитанных на каждом из потоков.
  89.  
  90.     for (int i = 0; i < n; i++)
  91.     {
  92.         sum += sqrtl(arr[i]);
  93.     }
  94.     time3 = omp_get_wtime() - time;
  95.     sum3 = sum;
  96.     //--------------------------------------------
  97.         //Вывод результатов
  98.     std::cout << "-----------------------------------------------------------------" << std::endl;
  99.     std::cout << "Однопоточное выполнение: " << std::endl;
  100.     std::cout << "\tРезультат =  " << sum1 << std::endl;
  101.     std::cout << "\tВремя выполнения =  " << time1 << " мс" << std::endl;
  102.  
  103.     std::cout << "Многопоточное выполнение (" << p << " нити), через critical: " << std::endl;
  104.     std::cout << "\tРезультат =  " << sum2 << std::endl;
  105.     std::cout << "\tВремя выполнения =  " << time2 << " мс" << std::endl;
  106.  
  107.     std::cout << "Многопоточное выполнение (" << p << " нити), через reduction: " << std::endl;
  108.     std::cout << "\tРезультат =  " << sum3 << std::endl;
  109.     std::cout << "\tВремя выполнения =  " << time3 << " мс" << std::endl;
  110.     std::cout << "-----------------------------------------------------------------" << std::endl;
  111.  
  112.     delete[] arr;
  113.     system("pause");
  114.     return 0;
  115. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement