Bagikan melalui


Pustaka Pola Paralel (PPL)

Pustaka Pola Paralel (PPL) menyediakan model pemrograman imperatif yang mempromosikan skalabilitas dan kemudahan penggunaan untuk mengembangkan aplikasi bersamaan. PPL dibangun berdasarkan komponen penjadwalan dan manajemen sumber daya dari Concurrency Runtime. Ini meningkatkan tingkat abstraksi antara kode aplikasi Anda dan mekanisme utas yang mendasar dengan menyediakan algoritma generik dan tipe aman serta wadah yang memproses data secara paralel. PPL juga memungkinkan Anda mengembangkan aplikasi yang menskalakan dengan memberikan alternatif untuk status bersama.

PPL menyediakan fitur-fitur berikut:

  • Parallelisme Tugas: mekanisme yang didasarkan pada Windows ThreadPool untuk menjalankan beberapa item kerja (tugas) secara paralel

  • Algoritma Paralel: algoritma generik yang bekerja di atas Concurrency Runtime untuk memproses koleksi data secara paralel

  • Kontainer dan objek paralel: jenis kontainer generik yang menyediakan akses bersamaan yang aman ke elemennya

Contoh

PPL menyediakan model pemrograman yang menyerupai Pustaka Standar C++. Contoh berikut menunjukkan banyak fitur PPL. Ini menghitung beberapa angka Fibonacci secara serial dan paralel. Kedua komputasi bertindak pada objek std::array . Contohnya juga mencetak ke konsol waktu yang diperlukan untuk melakukan kedua komputasi.

Versi serial menggunakan algoritma C++ Standard Library std::for_each untuk melintasi array dan menyimpan hasilnya dalam objek std::vector . Versi paralel melakukan tugas yang sama, tetapi menggunakan algoritma PPL concurrency::parallel_for_each dan menyimpan hasilnya dalam objek concurrency::concurrent_vector. Kelas ini concurrent_vector memungkinkan setiap iterasi perulangan untuk menambahkan elemen secara bersamaan tanpa persyaratan untuk menyinkronkan akses tulis ke kontainer.

Karena parallel_for_each bertindak bersamaan, versi paralel dari contoh ini harus mengurutkan concurrent_vector objek untuk menghasilkan hasil yang sama dengan versi seri.

Perhatikan bahwa contoh ini menggunakan cara sederhana untuk menghitung bilangan Fibonacci; namun, metode ini menunjukkan bagaimana Runtime Konkurensi dapat meningkatkan kinerja perhitungan yang memakan waktu lama.

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

Contoh output berikut adalah untuk komputer yang memiliki empat prosesor.

serial time: 9250 ms
parallel time: 5726 ms

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

Setiap iterasi membutuhkan jumlah waktu yang berbeda untuk selesai. Performa parallel_for_each ditentukan oleh operasi yang selesai terakhir. Oleh karena itu, Anda tidak boleh mengharapkan peningkatan performa linier antara versi serial dan paralel dari contoh ini.

Judul Deskripsi
Paralelisme Tugas Menjelaskan peran tugas dan grup tugas di PPL.
Algoritma Paralel Menjelaskan cara menggunakan algoritma paralel seperti parallel_for dan parallel_for_each.
Kontainer dan Objek Paralel Menjelaskan berbagai kontainer dan objek paralel yang disediakan oleh PPL.
Pembatalan di PPL Menjelaskan cara membatalkan pekerjaan yang sedang dilakukan oleh algoritma paralel.
Runtime Konkurensi Deskripsi tentang Concurrency Runtime, yang menyederhanakan pemrograman paralel, serta memuat tautan ke topik-topik terkait.