Aracılığıyla paylaş


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 combinableperformans 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ı