Share via


Paralel Desen Kitaplığı (PPL)

Paralel Desenler Kitaplığı (PPL), eşzamanlı uygulamalar geliştirmek için ölçeklenebilirliği ve kullanım kolaylığını destekleyen kesinlik temelli bir programlama modeli sağlar. PPL, Eşzamanlılık Çalışma Zamanı'nın zamanlama ve kaynak yönetimi bileşenlerini kullanır. Paralel olarak veriler üzerinde hareket eden genel, tür açısından güvenli algoritmalar ve kapsayıcılar sağlayarak uygulama kodunuzla temel alınan iş parçacığı oluşturma mekanizması arasındaki soyutlama düzeyini yükseltir. PPL, paylaşılan duruma alternatifler sağlayarak ölçeklendirilen uygulamalar geliştirmenize de olanak tanır.

PPL aşağıdaki özellikleri sağlar:

  • Görev Paralelliği: Birkaç iş öğesini (görevleri) paralel olarak yürütmek için Windows ThreadPool'un üzerinde çalışan bir mekanizma

  • Paralel algoritmalar: Paralel veri koleksiyonları üzerinde işlem yapmak için Eşzamanlılık Çalışma Zamanı'nın üzerinde çalışan genel algoritmalar

  • Paralel kapsayıcılar ve nesneler: öğelerine güvenli eşzamanlı erişim sağlayan genel kapsayıcı türleri

Örnek

PPL, C++ Standart Kitaplığına benzeyen bir programlama modeli sağlar. Aşağıdaki örnekte PPL'nin birçok özelliği gösterilmektedir. Birkaç Fibonacci sayısını seri olarak ve paralel olarak hesaplar. her iki hesaplama da std ::array nesnesi üzerinde işlem gerçekleştirir. Örnek, her iki hesaplamayı gerçekleştirmek için gereken süreyi konsola da yazdırır.

Seri sürüm, diziden geçiş yapmak için C++ Standart Kitaplığı std::for_each algoritmasını kullanır ve sonuçları bir std::vector nesnesinde depolar. Paralel sürüm aynı görevi gerçekleştirir, ancak ppl eşzamanlılık::p arallel_for_each algoritmasını kullanır ve sonuçları eşzamanlılık ::concurrent_vector nesnesinde depolar. sınıfı, concurrent_vector kapsayıcıya yazma erişimini eşitleme gereksinimi olmadan her döngü yinelemesinin eşzamanlı olarak öğe eklemesini sağlar.

Eşzamanlı parallel_for_each olarak hareket ettiğinden, bu örneğin paralel sürümü, seri sürümle aynı sonuçları elde etmek için nesneyi sıralamalıdır concurrent_vector .

Örnekte Fibonacci sayılarını hesaplamak için saf bir yöntem kullanıldığına dikkat edin; ancak bu yöntem Eşzamanlılık Çalışma Zamanı'nın uzun hesaplamaların performansını nasıl geliştirebileceğini gösterir.

// parallel-fibonacci.cpp
// compile with: /EHsc
#include <windows.h>
#include <ppl.h>
#include <concurrent_vector.h>
#include <array>
#include <vector>
#include <tuple>
#include <algorithm>
#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;
}

// Computes the nth Fibonacci number.
int fibonacci(int n)
{
   if(n < 2)
      return n;
   return fibonacci(n-1) + fibonacci(n-2);
}

int wmain()
{
   __int64 elapsed;

   // An array of Fibonacci numbers to compute.
   array<int, 4> a = { 24, 26, 41, 42 };

   // The results of the serial computation.
   vector<tuple<int,int>> results1;

   // The results of the parallel computation.
   concurrent_vector<tuple<int,int>> results2;

   // Use the for_each algorithm to compute the results serially.
   elapsed = time_call([&] 
   {
      for_each (begin(a), end(a), [&](int n) {
         results1.push_back(make_tuple(n, fibonacci(n)));
      });
   });   
   wcout << L"serial time: " << elapsed << L" ms" << endl;
   
   // Use the parallel_for_each algorithm to perform the same task.
   elapsed = time_call([&] 
   {
      parallel_for_each (begin(a), end(a), [&](int n) {
         results2.push_back(make_tuple(n, fibonacci(n)));
      });

      // Because parallel_for_each acts concurrently, the results do not 
      // have a pre-determined order. Sort the concurrent_vector object
      // so that the results match the serial version.
      sort(begin(results2), end(results2));
   });   
   wcout << L"parallel time: " << elapsed << L" ms" << endl << endl;

   // Print the results.
   for_each (begin(results2), end(results2), [](tuple<int,int>& pair) {
      wcout << L"fib(" << get<0>(pair) << L"): " << get<1>(pair) << endl;
   });
}

Aşağıdaki örnek çıkış, dört işlemcisi olan bir bilgisayara yöneliktir.

serial time: 9250 ms
parallel time: 5726 ms

fib(24): 46368
fib(26): 121393
fib(41): 165580141
fib(42): 267914296

Döngünün her yinelemesinin bitmek için farklı bir süre gerekir. 'nin parallel_for_each performansı, en son biten işlemle sınırlanır. Bu nedenle, bu örneğin seri ve paralel sürümleri arasında doğrusal performans geliştirmeleri beklememelisiniz.

Title Tanım
Görev Paralelliği PPL'deki görevlerin ve görev gruplarının rolünü açıklar.
Paralel Algoritmalar ve parallel_for_eachgibi parallel_for paralel algoritmaların nasıl kullanılacağını açıklar.
Paralel Kapsayıcılar ve Nesneler PPL tarafından sağlanan çeşitli paralel kapsayıcıları ve nesneleri açıklar.
PPL'de İptal Paralel algoritma tarafından gerçekleştirilen çalışmanın nasıl iptal edileceğini açıklar.
Eşzamanlılık Çalışma Zamanı Paralel programlamayı basitleştiren ve ilgili konulara bağlantılar içeren Eşzamanlılık Çalışma Zamanı'nı açıklar.