Aracılığıyla paylaş


Nasıl yapılır: Eşzamanlılık Çalışma Zamanı Kullanmak üzere Döngü için bir OpenMP paralelini Dönüştürme

Bu örnekte OpenMP paralelini kullanan temel bir döngünün nasıl dönüştürüldüğü veeşzamanlılık çalışma zamanı eşzamanlılığı::p arallel_for algoritmasını kullanmak için yönergelerin nasıl dönüştürüldüğü gösterilmektedir.

Örnek - asal sayı

Bu örnekte, rastgele değerler dizisindeki asal sayıların sayısını hesaplamak için hem OpenMP hem de Eşzamanlılık Çalışma Zamanı kullanılır.

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

Bu örnek aşağıdaki çıkışı oluşturur.

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

parallel_for Algoritma ve OpenMP 3.0, dizin türünün imzalı bir tam sayı türü veya imzasız bir tam sayı türü olmasını sağlar. Algoritma ayrıca parallel_for belirtilen aralığın imzalı bir türün taşmamasını da sağlar. OpenMP 2.0 ve 2.5 sürümleri yalnızca imzalı integral dizin türlerine izin verir. OpenMP ayrıca dizin aralığını doğrulamaz.

Bu örneğin Eşzamanlılık Çalışma Zamanı'nı kullanan sürümü, eşitleme gerektirmeden sayaç değerini artırmak için atomik yönerge yerine concurrency::combinable nesnesini de kullanır.

ve diğer paralel algoritmalar hakkında parallel_for daha fazla bilgi için bkz . Paralel Algoritmalar. sınıfı hakkında combinable daha fazla bilgi için bkz . Paralel Kapsayıcılar ve Nesneler.

Örnek - std::array kullanma

Bu örnek, yerel dizi yerine std ::array nesnesi üzerinde işlem yapmak için öncekini değiştirir. OpenMP sürüm 2.0 ve 2.5 yalnızca bir parallel_for yapıda imzalı integral dizin türlerine izin sağladığından, C++ Standart Kitaplığı kapsayıcısının öğelerine paralel olarak erişmek için yineleyicileri kullanamazsınız. Paralel Desenler Kitaplığı (PPL), C++ Standart Kitaplığı tarafından sağlananlar gibi yinelemeli bir kapsayıcıda görevleri paralel olarak gerçekleştiren eşzamanlılık::p arallel_for_each algoritmasını sağlar. Algoritmanın kullandığı bölümleme mantığını parallel_for kullanır. Algoritma parallel_for_each , C++ Standart Kitaplığı std::for_each algoritmasına parallel_for_each benzer, ancak algoritma görevleri eşzamanlı olarak yürütür.

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

Kod Derleniyor

Örnek kodu kopyalayıp bir Visual Studio projesine yapıştırın veya adlı concrt-omp-count-primes.cpp bir dosyaya yapıştırın ve ardından bir Visual Studio Komut İstemi penceresinde aşağıdaki komutu çalıştırın.

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

Ayrıca bkz.

OpenMP döngüsünden Eşzamanlılık Çalışma Zamanına geçiş
Paralel Algoritmalar
Paralel Kapsayıcılar ve Nesneler