Aracılığıyla paylaş


Nasıl yapılır: performansı artırmak için combinable kullan

Bu örnek, nasıl kullanılacağını gösterir concurrency::combinable class sayıların toplamını hesaplamak için bir std::array asal olan nesne. combinable Class paylaşılan durum ortadan kaldırarak performansı artırır.

İpucu

Bazı durumlarda, harita paralel (concurrency::parallel_transform) ve azaltma (eşzamanlılık:: parallel_reduce) üzerinde performans artışı sağlayabilir combinable.Kullandığı eşleştirmek ve bu örnek olarak aynı sonuçları üretmek için işlemleri azaltan bir örnek için bkz: Paralel algoritmalar.

Örnek

Aşağıdaki örnek std::accumulate asal olan bir dizideki öğelerin toplamı hesaplamak için işlevi. Bu örnekte, a olan bir array nesnesi ve is_prime işlevi giriş değeri asal olup olmadığını belirler.

prime_sum = accumulate(begin(a), end(a), 0, [&](int acc, int i) {
   return acc + (is_prime(i) ? i : 0);
});

Aşağıdaki örnek, önceki örnekte parallelize naïve yolu gösterir. Bu örnek concurrency::parallel_for_each paralel dizi işlemek için kullanılan algoritma ve bir concurrency::critical_section nesne erişimi eşitlemek için prime_sum değişkeni. Bu örnek, her iş parçacığı paylaşılan kaynağın kullanılabilir olana kadar beklemeniz gerekir çünkü ölçeklenmez.

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();
});

Aşağıdaki örnek bir combinable önceki örnek performansını artırmak için nesne. Bu örnek, eşitleme nesnelerinde gereksinimini ortadan kaldırır; çünkü ölçekler combinable bağımsız olarak, görevini gerçekleştirmesi her iş parçacığı nesnesi sağlar.

A combinable nesnesi genellikle iki adımda kullanılır. İlk olarak, paralel olarak iş gerçekleştirerek belirtilecek hesaplamaları bir dizi üretir. Ardından, birleştirmek (veya azaltmak) hesaplamaları içine bir sonuç. Bu örnek concurrency::combinable::local yerel toplanacak bir başvuruyu almak için yöntem. Daha sonra kullanır concurrency::combinable::combine yöntemi ve bir std::plus yerel hesaplamaların sonucunu halinde birleştirmek için nesne.

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>());

Aşağıdaki örneğin paralel ve seri olarak asal sayıların hem toplamını hesaplar. Örneğin hem hesaplamaları gerçekleştirmek için gerekli olan süre 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 çıktı dört işlemci olan bir bilgisayar içindir.

1709600813
serial time: 6178 ms

1709600813
parallel time: 1638 ms

Kod Derleniyor

Kodu derlemek için kopyalayın ve sonra Visual Studio Project'te yapıştırın veya adlı bir dosyaya yapıştırın primes.cpp, paralel toplamı ve Visual Studio komut istemi penceresinde aşağıdaki komutu çalıştırın.

cl.exe /EHsc parallel-sum-of-primes.cpp

Güçlü Programlama

Kullandığı eşleştirmek ve aynı sonuçlar için işlemleri azaltma örnek için bkz: Paralel algoritmalar.

Ayrıca bkz.

Başvuru

combinable sınıfı

critical_section sınıfı

Kavramlar

Paralel kapsayıcıları ve nesneleri