방법: 동시성 런타임을 사용하기 위해 OpenMP parallel for 루프 변환
Openmp를 사용 하는 기본 루프를 변환 하는 방법을 보여 주는이 예제 병렬 및 에 대 한 동시성 런타임을 사용 하는 지시문 concurrency::parallel_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에서는 인덱스 범위의 유효성을 검사하지 않습니다.
버전 동시성 런타임을 사용 하 여이 예제에도 사용 하는 concurrency::combinable 대신 개체는 원자 지시문을 동기화 하지 않고도 카운터 값을 증가 시킬.
parallel_for 및 기타 병렬 알고리즘에 대한 자세한 내용은 병렬 알고리즘을 참조하십시오.combinable 클래스에 대한 자세한 내용은 병렬 컨테이너 및 개체를 참조하십시오.
이 예제에서는 네이티브 배열 대신 std::array 개체에서 동작하도록 이전 예제를 수정합니다.OpenMP 버전 2.0 및 2.5에서는 parallelfor 구문에 부호 있는 정수 인덱스 형식만 사용할 수 있으므로 반복기를 사용하여 STL(표준 템플릿 라이브러리) 컨테이너 요소에 병렬로 액세스할 수 없습니다.병렬 패턴 라이브러리 (PPL) 제공의 concurrency::parallel_for_each STL에서 제공과 같은 반복 되는 컨테이너에서 동시에 작업을 수행 하는 알고리즘입니다.이 알고리즘은 parallel_for 알고리즘에서 사용하는 것과 같은 분할 논리를 사용합니다.parallel_for_each 알고리즘은 parallel_for_each 알고리즘이 동시에 작업을 실행한다는 점을 제외하고는 STL 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 프로젝트에 붙여 또는 라는 파일에 붙여 omp 카운트 primes.cpp concrt 및 다음 Visual Studio 명령 프롬프트 창에서 다음 명령을 실행 합니다.
cl.exe /EHsc /openmp concrt-omp-count-primes.cpp