Cara: Mengonversi Perulangan OpenMP yang Menggunakan Variabel Pengurangan untuk Menggunakan Runtime Konkurensi

Contoh ini menunjukkan cara mengonversi paralelOpenMP untuk perulangan yang menggunakan klausul pengurangan untuk menggunakan Concurrency Runtime.

Klausa OpenMP reduction memungkinkan Anda menentukan satu atau beberapa variabel thread-private yang tunduk pada operasi pengurangan di akhir wilayah paralel. OpenMP telah menentukan serangkaian operator pengurangan. Setiap variabel pengurangan harus berupa skalar (misalnya, , intlong, dan float). OpenMP juga mendefinisikan beberapa batasan tentang bagaimana variabel pengurangan digunakan di wilayah paralel.

Pustaka Pola Paralel (PPL) menyediakan kelas konkurensi::combinable , yang menyediakan penyimpanan lokal utas yang dapat digunakan kembali yang memungkinkan Anda melakukan komputasi terperinci lalu menggabungkan komputasi tersebut ke dalam hasil akhir. Kelas combinable adalah templat yang bertindak pada jenis skalar dan kompleks. Untuk menggunakan combinable kelas , lakukan sub-komputasi dalam isi konstruksi paralel dan kemudian panggil konkurensi::combinable::combine atau concurrency::combinable::combine_each method untuk menghasilkan hasil akhir. Metode combine dan combine_each masing-masing mengambil fungsi gabungan yang menentukan cara menggabungkan setiap pasangan elemen. Oleh karena itu, combinable kelas tidak dibatasi untuk serangkaian operator pengurangan tetap.

Contoh

Contoh ini menggunakan OpenMP dan Concurrency Runtime untuk menghitung jumlah 35 angka Fibonacci pertama.

// 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);
}

Contoh ini menghasilkan output berikut.

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.

Untuk informasi selengkapnya tentang combinable kelas, lihat Kontainer dan Objek Paralel.

Mengompilasi Kode

Salin kode contoh dan tempelkan dalam proyek Visual Studio, atau tempelkan dalam file yang diberi nama concrt-omp-fibonacci-reduction.cpp lalu jalankan perintah berikut di jendela Prompt Perintah Visual Studio.

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

Baca juga

Migrasi dari OpenMP ke Runtime Konkurensi
Kontainer dan Objek Paralel