Aplicaciones de Windows
Collapse the table of content
Expand the table of content
Información
El tema que ha solicitado se muestra abajo. Sin embargo, este tema no se encuentra en la biblioteca.

Parallel Patterns Library (PPL)

 

Para obtener la documentación más reciente de Visual Studio 2017 RC, consulte Documentación de Visual Studio 2017 RC.

La Biblioteca de patrones de procesamiento paralelo (PPL) proporciona un modelo de programación imperativo que favorece la escalabilidad y facilidad de uso para desarrollar aplicaciones simultáneas. PPL se basa en los componentes de administración de recursos y programación del Runtime de simultaneidad. Eleva el nivel de abstracción entre el código de aplicación y el mecanismo de subprocesamiento subyacente proporcionando contenedores y algoritmos genéricos, con seguridad de tipos, que actúan sobre los datos en paralelo. PPL también permite desarrollar aplicaciones que escalan proporcionando alternativas al estado compartido.

PPL proporciona las características siguientes.

  • Paralelismo de tareas: un mecanismo que se basa en el grupo de subprocesos de Windows para ejecutar varios elementos de trabajo (tareas) en paralelo

  • Algoritmos paralelos: algoritmos genéricos que se basa en el Runtime de simultaneidad para actuar en colecciones de datos en paralelo

  • Contenedores y objetos paralelos: tipos de contenedor genéricos que proporcionan acceso simultáneo seguro a sus elementos

PPL proporciona un modelo de programación que se parece al de la Biblioteca de plantillas estándar (STL). En el ejemplo siguiente se muestran muchas características de PPL: Calcula varios números de Fibonacci en serie y en paralelo. Ambos cálculos actúan sobre un std:: Array objeto. También se imprime en la consola el tiempo necesario para realizar ambos cálculos.

La versión en serie usa STL std:: for_each algoritmo para atravesar la matriz y almacena los resultados en un std:: vector objeto. La versión en paralelo realiza la misma tarea, pero usa la biblioteca PPL Concurrency:: parallel_for_each algoritmo y almacena los resultados en un Concurrency:: concurrent_vector objeto. La clase concurrent_vector permite que cada iteración del bucle agregue los elementos de forma simultánea, sin el requisito de sincronizar el acceso de escritura en el contenedor.

Dado que parallel_for_each actúa de manera simultánea, la versión del cálculo en paralelo de este ejemplo debe ordenar el objeto concurrent_vector para generar los mismos resultados que la versión del cálculo en serie.

Observe que en el ejemplo se usa un método sencillo para calcular los números de Fibonacci; sin embargo, este método muestra cómo el Runtime de simultaneidad puede mejorar el rendimiento en el caso de cálculos largos.

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

La siguiente salida de ejemplo corresponde a un equipo con cuatro procesadores.

serial time: 9250 ms  
parallel time: 5726 ms  
 
fib(24): 46368  
fib(26): 121393  
fib(41): 165580141  
fib(42): 267914296  

Cada iteración del bucle requiere una cantidad de tiempo diferente para finalizar. La operación que finaliza en último lugar limita el rendimiento de parallel_for_each. Por consiguiente, no debería esperar mejoras de rendimiento lineales entre las versiones en serie y en paralelo de este ejemplo.

TítuloDescripción
Paralelismo de tareasDescribe el rol de las tareas y los grupos de tareas en la biblioteca PPL.
Algoritmos paralelosSe describe cómo usar algoritmos paralelos, como parallel_for y parallel_for_each.
Contenedores y objetos paralelosSe describen los distintos objetos y contenedores paralelos que proporciona PPL.
CancelaciónExplica cómo cancelar el trabajo realizado por un algoritmo paralelo.
Runtime de simultaneidadSe describe el Runtime de simultaneidad, que simplifica la programación en paralelo, y contiene vínculos a los temas relacionados.
© 2017 Microsoft