다음을 통해 공유


방법: 동시성 런타임을 사용하기 위해 OpenMP parallel for 루프 변환

이 예제에서는 OpenMP 병렬을 사용하는 기본 루프를 변환하고 지시문에서 동시성 런타임 동시성::p arallel_for 알고리즘을 사용하는 방법을 보여 줍니다.

예제 - 소수 개수

이 예제에서는 OpenMP와 동시성 런타임을 모두 사용하여 임의 값 배열의 소수 수를 계산합니다.

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

이 예제의 결과는 다음과 같습니다.

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

parallel_for 알고리즘 및 OpenMP 3.0을 사용하면 인덱스 형식이 부호 있는 정수 계열 형식 또는 부호 없는 정수 계열 형식이 될 수 있습니다. 또한 알고리즘은 parallel_for 지정된 범위가 서명된 형식을 오버플로하지 않도록 합니다. OpenMP 버전 2.0 및 2.5는 서명된 정수 인덱스 형식만 허용합니다. 또한 OpenMP는 인덱스 범위의 유효성을 검사하지 않습니다.

동시성 런타임을 사용하는 이 예제의 버전에서는 원자성 지시문 대신 동시성::결합 가능한 개체를 사용하여 동기화 없이 카운터 값을 증분합니다.

병렬 알고리즘 및 기타 병렬 알고리즘에 대한 parallel_for 자세한 내용은 병렬 알고리즘을 참조 하세요. 클래스에 대한 combinable 자세한 내용은 병렬 컨테이너 및 개체를 참조 하세요.

예제 - std::array 사용

다음은 네이티브 배열 대신 std::array 개체에서 작동하도록 이전 개체를 수정하는 예제입니다. OpenMP 버전 2.0 및 2.5는 구문에서만 부호 있는 parallel_for 정수 인덱스 형식을 허용하므로 반복기를 사용하여 C++ 표준 라이브러리 컨테이너의 요소에 병렬로 액세스할 수 없습니다. PPL(병렬 패턴 라이브러리)은 C++ 표준 라이브러리에서 제공하는 것과 같은 반복 컨테이너에서 병렬로 작업을 수행하는 동시성::p arallel_for_each 알고리즘을 제공합니다. 알고리즘에서 사용하는 것과 동일한 분할 논리를 parallel_for 사용합니다. 알고리즘은 parallel_for_each 작업을 동시에 실행한다는 parallel_for_each 점을 제외하고 C++ 표준 라이브러리 std::for_each 알고리즘과 유사합니다.

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

코드 컴파일

예제 코드를 복사하여 Visual Studio 프로젝트에 붙여넣거나 이름이 지정된 concrt-omp-count-primes.cpp 파일에 붙여넣은 다음 Visual Studio 명령 프롬프트 창에서 다음 명령을 실행합니다.

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

참고 항목

OpenMP에서 동시성 런타임으로 마이그레이션
병렬 알고리즘
병렬 컨테이너 및 개체