Nasıl yapılır: Performansı arttırmak için combinable Kullanma
Bu örnekte, asal olan bir std::array nesnesindeki sayıların toplamını hesaplamak için concurrency::combinable sınıfının nasıl kullanılacağı gösterilmektedir. sınıfı, combinable
paylaşılan durumu ortadan kaldırarak performansı artırır.
İpucu
Bazı durumlarda paralel eşleme (eşzamanlılık::p arallel_transform) ve azaltma (eşzamanlılık:: parallel_reduce) üzerinde combinable
performans iyileştirmeleri sağlayabilir. Bu örnekle aynı sonuçları elde etmek için eşleme ve azaltma işlemlerini kullanan bir örnek için bkz . Paralel Algoritmalar.
Örnek - birikmesi
Aşağıdaki örnek, bir dizideki asal öğelerin toplamını hesaplamak için std::accumulate işlevini kullanır. Bu örnekte bir a
array
nesnedir ve işlev giriş değerinin is_prime
asal olup olmadığını belirler.
prime_sum = accumulate(begin(a), end(a), 0, [&](int acc, int i) {
return acc + (is_prime(i) ? i : 0);
});
Örnek - parallel_for_each
Aşağıdaki örnekte, önceki örneği paralel hale getirmek için basit bir yol gösterilmektedir. Bu örnekte, diziyi paralel olarak işlemek için eşzamanlılık::p arallel_for_each algoritması ve değişkene erişimi prime_sum
eşitlemek için bir eşzamanlılık::critical_section nesnesi kullanılır. Her iş parçacığının paylaşılan kaynağın kullanılabilir olmasını beklemesi gerektiğinden bu örnek ölçeklendirilmiyor.
critical_section cs;
prime_sum = 0;
parallel_for_each(begin(a), end(a), [&](int i) {
cs.lock();
prime_sum += (is_prime(i) ? i : 0);
cs.unlock();
});
Örnek - birleştirilebilir
Aşağıdaki örnek, önceki örneğin performansını geliştirmek için bir combinable
nesnesi kullanır. Bu örnek, eşitleme nesneleri gereksinimini ortadan kaldırır; nesne her iş parçacığının combinable
görevini bağımsız olarak gerçekleştirmesine olanak sağladığından ölçeklendirilir.
Nesne combinable
genellikle iki adımda kullanılır. İlk olarak, paralel çalışma yaparak bir dizi ayrıntılı hesaplama üretin. Ardından, hesaplamaları nihai bir sonuç olarak birleştirin (veya azaltın). Bu örnekte, yerel toplama başvuru almak için eşzamanlılık::combinable::local yöntemi kullanılır. Ardından concurrency::combinable::combine yöntemini ve std::p lus nesnesini kullanarak yerel hesaplamaları nihai sonuçla birleştirir.
combinable<int> sum;
parallel_for_each(begin(a), end(a), [&](int i) {
sum.local() += (is_prime(i) ? i : 0);
});
prime_sum = sum.combine(plus<int>());
Örnek - seri ve paralel
Aşağıdaki tam örnek, asal sayıların toplamını hem seri olarak hem de paralel olarak hesaplar. Örnek, her iki hesaplamayı gerçekleştirmek için gereken süreyi konsola yazdırır.
// parallel-sum-of-primes.cpp
// compile with: /EHsc
#include <windows.h>
#include <ppl.h>
#include <array>
#include <numeric>
#include <iostream>
using namespace concurrency;
using namespace std;
// Calls the provided work function and returns the number of milliseconds
// that it takes to call that function.
template <class Function>
__int64 time_call(Function&& f)
{
__int64 begin = GetTickCount();
f();
return GetTickCount() - begin;
}
// 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;
}
int wmain()
{
// Create an array object that contains 200000 integers.
array<int, 200000> a;
// Initialize the array such that a[i] == i.
iota(begin(a), end(a), 0);
int prime_sum;
__int64 elapsed;
// Compute the sum of the numbers in the array that are prime.
elapsed = time_call([&] {
prime_sum = accumulate(begin(a), end(a), 0, [&](int acc, int i) {
return acc + (is_prime(i) ? i : 0);
});
});
wcout << prime_sum << endl;
wcout << L"serial time: " << elapsed << L" ms" << endl << endl;
// Now perform the same task in parallel.
elapsed = time_call([&] {
combinable<int> sum;
parallel_for_each(begin(a), end(a), [&](int i) {
sum.local() += (is_prime(i) ? i : 0);
});
prime_sum = sum.combine(plus<int>());
});
wcout << prime_sum << endl;
wcout << L"parallel time: " << elapsed << L" ms" << endl << endl;
}
Aşağıdaki örnek çıkış, dört işlemcisi olan bir bilgisayara yöneliktir.
1709600813
serial time: 6178 ms
1709600813
parallel time: 1638 ms
Kod Derleniyor
Kodu derlemek için kopyalayın ve visual studio projesine yapıştırın veya adlı parallel-sum-of-primes.cpp
bir dosyaya yapıştırın ve ardından visual studio komut istemi penceresinde aşağıdaki komutu çalıştırın.
cl.exe /EHsc parallel-sum-of-primes.cpp
Güçlü Programlama
Aynı sonuçları elde etmek için eşleme ve azaltma işlemlerini kullanan bir örnek için bkz . Paralel Algoritmalar.
Ayrıca bkz.
Paralel Kapsayıcılar ve Nesneler
combinable Sınıfı
critical_section Sınıfı