Может кто-нибудь помочь мне распараллелить этот код C ++? - PullRequest
0 голосов
/ 05 февраля 2019

Итак, мне было поручено найти способ распараллелить эту простую проблему C ++.Проблема в том, что ... я действительно ... ДЕЙСТВИТЕЛЬНО борюсь с концепциями параллельного программирования и понятия не имею, что делать.Ниже приведены шаги, которые необходимо предпринять:

1) принять положительное целое число N в качестве аргумента
2) создать массив целых чисел размера N
3) заполнить целые числа из диапазона [1,1000]
4) Найти наибольшее целое число и сумму массива параллельно
5) вывести наибольшее целое число и сумму массива.

Это было достаточно просто, пока я не добрался до шага 4. Я понятия не имею, как распараллелить этот код.Я слышал о таких понятиях, как многопоточность и многопоточность, но у меня почти нет идеи, как реализовать их в C ++, и я мог бы действительно использовать некоторую помощь + подробное объяснение с этим.Мне еще предстоит найти конкретный пример параллельной распараллеливания программы на C ++, который имеет смысл для меня.

#include  <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

int main(){

cout << "Enter the Size of the Array (N):  \n ";
int N;
cin >> N;

int array[N];
int largest_number = 0;
int sum = 0;

srand(time(0));
cout << "Populating Array...\n";

//  Filling up the Array  with values
    for(int i =0; i < N; i++)
    {

    array[i] =  (rand() % 1000) + 1;

    }


// Finding the largest value and calculating sum of the array
    for( int j  = 0; j < N; j++)
    {

    sum += array[j];

    if( array[j] > largest_number)
    {largest_number = array[j];}

    }

cout << "Output: \n";
cout << "Maximum:  " <<  largest_number << ";" <<  "Sum: " <<  sum;
cout << "\n";

 }

В нынешнем виде код работает нормально.Мне просто нужно показать примеры параллельного программирования.

Что касается ожиданий, я мог бы реализовать таймер в коде, чтобы проверить, насколько быстрее будет распараллеливание этого кода, но я хочу убедиться, что он работаетпервый.Спасибо

Ответы [ 2 ]

0 голосов
/ 05 февраля 2019

С C ++ 17:

std::vector<int> array(N);
// ...
auto sum = reduce(std::execution::par, arr.begin(), arr.end(), 0);
0 голосов
/ 05 февраля 2019

Для многих простых параллельных задач OpenMP будет вашим лучшим выбором.

Он уже включен во все компиляторы C ++, является зрелым отраслевым стандартом, предлагает возможность разгрузки на графические процессоры и минимально инвазивен.к существующему коду, позволяя вам легко вернуться к последовательной формулировке.

Ниже я переписал ваш код для использования OpenMP.Я также сделал несколько других изменений.

Я опустил строку using namespace std.Эта строка потенциально опасна, потому что стандартная библиотека - big , и это перетягивает все это в глобальное пространство имен, где она может потенциально конфликтовать с другими библиотеками, которые вы можете использовать.

Я также отбросилint array[N].Этот код был опасен с самого начала, потому что подобные массивы действительно могут быть определены, только если N является константой времени компиляции.Что вам действительно нужно, так это динамическое распределение.В C ++ лучший способ сделать это с помощью std::vector (см. Ниже).

Наконец, мы переходим к циклу for.OpenMP лучше всего подходит для сценариев, в которых каждая итерация цикла независима .Это означает, что если вам будет трудно использовать его с кодом, подобным a[i]=3*a[i-1].Тем не менее, ваш цикл может быть выполнен в соответствии с шаблоном.

Вызов OpenMP:

#pragma omp parallel for reduction(+:sum) reduction(max:largest_number)

сообщает компьютеру

Запустите столько потоков, сколько существуетявляются ядрами и делят петлю равномерно между этими потоками.Дайте каждому потоку свою собственную личную копию переменных sum и largest_number.Как только каждый поток завершит свою работу, объедините приватные переменные sum в глобальную переменную sum, используя оператор +.Кроме того, объедините все частные largest_number переменные в глобальную largest_number переменную, используя оператор max.

Как видите, эта единственная строка представляет собой очень краткое представление того, что необходимобыть сделаноДаже если вы планируете использовать более сложную среду, такую ​​как Intel Thread Building Blocks, или использовать собственную std::thread, OpenMP может стать хорошим способом создания прототипа решения.Это также хорошо играет с TBB и std::thread.

//Compile with g++ main.cpp -fopenmp
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <vector>

int main(){
  std::cout << "Enter the Size of the Array (N): ";
  int N;
  std::cin >> N;

  std::vector<int> array(N);

  //WARNING: This is a poor way of choosing a seed
  srand(time(0));

  std::cout << "Populating Array...\n";
  for(int i =0; i < N; i++)
    array[i] =  (rand() % 1000) + 1; //WARNING: This is a poor way to choose random numbers

  int largest_number = 0;
  int sum = 0;

  // Finding the largest value and calculating sum of the array
  #pragma omp parallel for reduction(+:sum) reduction(max:largest_number)
  for( int j  = 0; j < N; j++){
    sum += array[j];

    if(array[j] > largest_number)
      largest_number = array[j];
  }

  std::cout << "Output: \n";
  std::cout << "Maximum:  " <<  largest_number << ";" <<  "Sum: " <<  sum;
  std::cout << "\n";
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...