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
Geri Bildirim
https://aka.ms/ContentUserFeedback.
Çok yakında: 2024 boyunca, içerik için geri bildirim mekanizması olarak GitHub Sorunları’nı kullanımdan kaldıracak ve yeni bir geri bildirim sistemiyle değiştireceğiz. Daha fazla bilgi için bkz.Gönderin ve geri bildirimi görüntüleyin