Поделиться через


Практическое руководство. Преобразование цикла OpenMP, использующего переменную сокращения для использования среды выполнения с параллелизмом

В этом примере показано, как преобразовать для использования среды выполнения с параллелизмом цикл parallelfor OpenMP, использующий предложение снижение.

Предложение reduction OpenMP позволяет задавать одну или несколько переменных, закрытых в определенных потоках, к которым в конце параллельной области применяется операция редукции.OpenMP предопределяет набор операторов редукции.Все переменные редукции должны быть скалярными (например, int, long и float).OpenMP также определяет несколько ограничений на использование переменных редукции в параллельной области.

Параллельные шаблоны (PPL) обеспечивает concurrency::combinable класс, который предоставляет хранилище для многократного использования, локальной памяти потока, позволяет выполнять вычисления детализированное и затем объединить эти вычисления конечного результата.Класс combinable — это шаблон, работающий как со скалярными, так и со сложными типами.Использование combinable класса, выполнение sub-computations в теле параллельной конструкции и затем вызвать concurrency::combinable::combine или concurrency::combinable::combine_each метод для получения окончательного результата.Методы combine и combine_each принимают функцию combine, которая указывает, как объединять пары элементов.Поэтому класс combinable не ограничен определенным набором операторов редукции.

Пример

В этом примере для вычисления суммы первых 35 чисел Фибоначчи используется как OpenMP, так и среда выполнения с параллелизмом.

// concrt-omp-fibonacci-reduction.cpp
// compile with: /EHsc /openmp
#include <ppl.h>
#include <iostream>

using namespace concurrency;
using namespace std;

// Computes the nth Fibonacci number.
// This function illustrates a lengthy operation and is therefore
// not optimized for performance.
int fibonacci(int n)
{
   if (n < 2)
      return n;

   // Compute the components in parallel.
   int n1, n2;
   parallel_invoke(
      [n,&n1] { n1 = fibonacci(n-1); },
      [n,&n2] { n2 = fibonacci(n-2); }
   );

   return n1 + n2;
}

// Uses OpenMP to compute the sum of Fibonacci numbers in parallel.
void omp_parallel_fibonacci_sum(int count)
{
   int sum = 0;
   #pragma omp parallel for reduction(+ : sum)
      for (int i = 0; i < count; ++i)
      {
         sum += fibonacci(i);
      }

   wcout << L"The sum of the first " << count << L" Fibonacci numbers is " 
         << sum << L'.' << endl;
}

// Uses the Concurrency Runtime to compute the sum of Fibonacci numbers in parallel.
void concrt_parallel_fibonacci_sum(int count) 
{
   combinable<int> sums;
   parallel_for(0, count, [&sums](int i)
      {
         sums.local() += fibonacci(i);
      });

   wcout << L"The sum of the first " << count << L" Fibonacci numbers is " 
         << sums.combine(plus<int>()) << L'.' << endl;
}

int wmain()
{
   const int count = 35;

   wcout << L"Using OpenMP..." << endl;
   omp_parallel_fibonacci_sum(count);

   wcout << L"Using the Concurrency Runtime..." << endl;
   concrt_parallel_fibonacci_sum(count);
}

В результате выполнения примера получается следующий результат:

Using OpenMP...
The sum of the first 35 Fibonacci numbers is 14930351.
Using the Concurrency Runtime...
The sum of the first 35 Fibonacci numbers is 14930351.

Дополнительные сведения о классе combinable см. в разделе Параллельные контейнеры и объекты.

Компиляция кода

Скопируйте код и вставьте его в проект Visual Studio или вставьте его в файл с именем concrt omp Фибоначчи reduction.cpp и запустите следующую команду в окне командной строки Visual Studio.

cl.exe /EHsc /openmp concrt-omp-fibonacci-reduction.cpp

См. также

Основные понятия

Переход от OpenMP к среде выполнения с параллелизмом

Параллельные контейнеры и объекты