Cara: Mengonversi paralel OpenMP untuk Perulangan untuk Menggunakan Runtime Konkurensi

Contoh ini menunjukkan cara mengonversi perulangan dasar yang menggunakan paralel OpenMP dan untuk arahan untuk menggunakan konkurensi Runtime Konkurensi::p arallel_untuk algoritma.

Contoh - jumlah utama

Contoh ini menggunakan OpenMP dan Runtime Konkurensi untuk menghitung jumlah angka utama dalam array nilai acak.

// concrt-omp-count-primes.cpp
// compile with: /EHsc /openmp
#include <ppl.h>
#include <random>
#include <array>
#include <iostream>

using namespace concurrency;
using namespace std;

// Determines whether the input value is prime.
bool is_prime(int n)
{
   if (n < 2)
      return false;
   for (int i = 2; i < n; ++i)
   {
      if ((n % i) == 0)
         return false;
   }
   return true;
}

// Uses OpenMP to compute the count of prime numbers in an array.
void omp_count_primes(int* a, size_t size)
{
   if (size == 0)
      return;

   size_t count = 0;
   #pragma omp parallel for
      for (int i = 0; i < static_cast<int>(size); ++i)
      {
         if (is_prime(a[i])) {
            #pragma omp atomic
               ++count;
         }
      }

   wcout << L"found " << count 
         << L" prime numbers." << endl;
}

// Uses the Concurrency Runtime to compute the count of prime numbers in an array.
void concrt_count_primes(int* a, size_t size)
{
   if (size == 0)
      return;

   combinable<size_t> counts;
   parallel_for<size_t>(0, size, [&](size_t i) 
   {
      if (is_prime(a[i])) {
         counts.local()++;
      }
   });

   wcout << L"found " << counts.combine(plus<size_t>()) 
         << L" prime numbers." << endl;
}

int wmain()
{
   // The length of the array.
   const size_t size = 1000000;
   
   // Create an array and initialize it with random values.
   int* a = new int[size];
   
   mt19937 gen(42);
   for (size_t i = 0; i < size; ++i) {
      a[i] = gen();
   }

   // Count prime numbers by using OpenMP and the Concurrency Runtime.

   wcout << L"Using OpenMP..." << endl;
   omp_count_primes(a, size);

   wcout << L"Using the Concurrency Runtime..." << endl;
   concrt_count_primes(a, size);

   delete[] a;
}

Contoh ini menghasilkan output berikut.

Using OpenMP...
found 107254 prime numbers.
Using the Concurrency Runtime...
found 107254 prime numbers.

parallel_for Algoritma dan OpenMP 3.0 memungkinkan jenis indeks menjadi jenis integral yang ditandatangani atau jenis integral yang tidak ditandatangani. parallel_for Algoritma juga memastikan bahwa rentang yang ditentukan tidak meluapkan jenis yang ditandatangani. OpenMP versi 2.0 dan 2.5 hanya memungkinkan jenis indeks integral yang ditandatangani. OpenMP juga tidak memvalidasi rentang indeks.

Versi contoh ini yang menggunakan Runtime Konkurensi juga menggunakan objek konkurensi::combinable sebagai pengganti direktif atom untuk menaikkan nilai penghitung tanpa memerlukan sinkronisasi.

Untuk informasi selengkapnya tentang parallel_for dan algoritma paralel lainnya, lihat Algoritma Paralel. Untuk informasi selengkapnya tentang combinable kelas, lihat Kontainer dan Objek Paralel.

Contoh - gunakan std::array

Contoh ini memodifikasi yang sebelumnya untuk bertindak pada objek std::array alih-alih pada array asli. Karena OpenMP versi 2.0 dan 2.5 memungkinkan jenis indeks integral yang ditandatangani hanya dalam parallel_for konstruksi, Anda tidak dapat menggunakan iterator untuk mengakses elemen kontainer Pustaka Standar C++ secara paralel. Pustaka Pola Paralel (PPL) menyediakan konkurensi::p arallel_for_each algoritma, yang melakukan tugas, secara paralel, pada kontainer iteratif seperti yang disediakan oleh Pustaka Standar C++. Ini menggunakan logika partisi yang sama dengan yang parallel_for digunakan algoritma. parallel_for_each Algoritma menyerupai algoritma C++ Standard Library std::for_each, kecuali bahwa parallel_for_each algoritma menjalankan tugas secara bersamaan.

// Uses OpenMP to compute the count of prime numbers in an 
// array object.
template<size_t Size>
void omp_count_primes(const array<int, Size>& a)
{
   if (a.size() == 0)
      return;

   size_t count = 0;
   int size = static_cast<int>(a.size());
   #pragma omp parallel for
      for (int i = 0; i < size; ++i)
      {
         if (is_prime(a[i])) {
            #pragma omp atomic
               ++count;
         }
      }

   wcout << L"found " << count 
         << L" prime numbers." << endl;
}

// Uses the Concurrency Runtime to compute the count of prime numbers in an 
// array object.
template<size_t Size>
void concrt_count_primes(const array<int, Size>& a)
{
   if (a.size() == 0)
      return;

   combinable<size_t> counts;
   parallel_for_each(begin(a), end(a), [&counts](int n) 
   {
      if (is_prime(n)) {
         counts.local()++;
      }
   });

   wcout << L"found " << counts.combine(plus<size_t>()) 
         << L" prime numbers." << endl;
}

Mengompilasi Kode

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

cl.exe /EHsc /openmp concrt-omp-count-primes.cpp

Baca juga

Migrasi dari OpenMP ke Runtime Konkurensi
Algoritma Paralel
Kontainer dan Objek Paralel