Для многих простых параллельных задач 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";
}