Algoritmos paralelos
O paralela padrões PPL (biblioteca) fornece os algoritmos que realizam simultaneamente o trabalho em coleções de dados. Esses algoritmos são semelhantes aos fornecidos pelo modelo Biblioteca STL (Standard).
Os algoritmos paralelos são compostos de funções existentes no Runtime de simultaneidade. Por exemplo, o Concurrency::parallel_for algoritmo usa uma Concurrency::structured_task_group objeto para realizar as iterações do loop paralelo. O parallel_for partições do algoritmo trabalham de maneira ideal, dada o número disponível de recursos de computação.
Seções
Este tópico descreve os seguintes algoritmos paralelos em detalhes:
Algoritmo de parallel_for
Algoritmo de parallel_for_each
Algoritmo de parallel_invoke
Algoritmo de parallel_for
O Concurrency::parallel_for repetidamente, o algoritmo realiza a mesma tarefa em paralelo. Cada uma dessas tarefas é parametrizada por um valor de iteração. Esse algoritmo é útil quando você tem um corpo de loop não compartilhar recursos entre as iterações do loop.
O parallel_for tarefas de partições do algoritmo de maneira ideal para execução paralela. Ele usa um algoritmo de roubo de trabalho para equilibrar a essas partições, cargas de trabalho são desbalanceadas. Quando uma iteração de loop bloqueia de forma cooperativa, o runtime redistribui o intervalo de iterações que é atribuído ao segmento atual para outros segmentos ou processadores. Da mesma forma, quando um thread conclui um intervalo de iterações, o runtime redistribui o trabalho de outros segmentos para esse segmento. O parallel_for também suporta um algoritmo aninhado paralelismo. Quando um loop paralelo contém outro loop paralelo, o runtime coordena os recursos de processamento entre os corpos de loop de maneira eficiente para execução em paralelo.
O parallel_for algoritmo tem duas versões sobrecarregadas. A primeira versão leva a uma função de trabalho (uma expressão lambda, o objeto de função ou o ponteiro de função), um valor final e um valor inicial. A segunda versão tem um valor inicial, um valor final, um valor pelo qual etapa e uma função de trabalho. A primeira versão dessa função usa 1 como o valor de etapa.
Você pode converter muitos for loops para usar parallel_for. No entanto, o parallel_for difere do algoritmo de for instrução das seguintes maneiras:
O parallel_for algoritmo parallel_for não executar as tarefas em uma ordem predeterminada.
O parallel_for não oferece suporte ao algoritmo de condições de terminação arbitrária. O parallel_for algoritmo pára quando o valor atual da variável de iteração é menor do que _Last.
O _Index_type o parâmetro de tipo deve ser um tipo integral. Esse tipo de integral pode ser assinado ou não assinado.
A iteração de loop deve ser em frente. O parallel_for algoritmo lança uma exceção do tipo std::invalid_argument se a _Step parâmetro é menor que 1.
O mecanismo de tratamento de exceção para o parallel_for algoritmo difere de um for loop. Se várias exceções ocorrem simultaneamente em um corpo do loop paralelo, o runtime propaga apenas uma das exceções para o thread que chamou parallel_for. Além disso, quando uma iteração do loop lança uma exceção, o tempo de execução não parar imediatamente o loop geral. Em vez disso, o loop é colocado no estado cancelado e o tempo de execução descarta todas as tarefas que ainda não iniciaram. Para obter mais informações sobre os algoritmos paralelos e de manipulação de exceção, consulte O Runtime de simultaneidade de manipulação de exceção.
Embora o parallel_for algoritmo não oferece suporte a condições de terminação arbitrário, você pode usar o cancelamento para parar todas as tarefas. Para obter mais informações sobre o cancelamento, consulte Cancelamento na PPL.
Observação |
---|
O custo de agendamento que resultados de balanceamento de carga e o suporte para recursos como o cancelamento não podem superar os benefícios de executar o corpo do loop em paralelo, especialmente quando o corpo do loop é relativamente pequeno. |
Exemplo
O exemplo a seguir mostra a estrutura básica da parallel_for algoritmo. Este exemplo imprime no console de cada valor no intervalo [1, 5] em paralelo.
// parallel-for-structure.cpp
// compile with: /EHsc
#include <ppl.h>
#include <array>
#include <sstream>
#include <iostream>
using namespace Concurrency;
using namespace std;
int wmain()
{
// Print each value from 1 to 5 in parallel.
parallel_for(1, 6, [](int value) {
wstringstream ss;
ss << value << L' ';
wcout << ss.str();
});
}
Este exemplo produz a saída de exemplo a seguir:
1 2 4 3 5
Porque o parallel_for algoritmo atua em cada item em paralelo, a ordem na qual os valores são impressas no console irá variar.
Para obter um exemplo completo que usa o parallel_for o algoritmo, consulte Como: Escrever um Loop de parallel_for.
go to top
Algoritmo de parallel_for_each
O Concurrency::parallel_for_each algoritmo realiza tarefas em um contêiner iterativo, tais como aqueles fornecidos pela STL, em paralelo. Ele usa a mesma lógica de particionamento que o parallel_for algoritmo usa.
O parallel_for_each algoritmo semelhante a STL std::for_each o algoritmo, exceto que o parallel_for_each algoritmo executa as tarefas simultaneamente. Como outros algoritmos paralelos, parallel_for_each não executar as tarefas em uma ordem específica.
Embora o parallel_for_each algoritmo funciona iteradores direta e iteradores de acesso aleatório, realiza melhor com acesso aleatório iteradores.
Exemplo
O exemplo a seguir mostra a estrutura básica da parallel_for_each algoritmo. Este exemplo imprime o console de cada valor em um std::array o objeto em paralelo.
// parallel-for-each-structure.cpp
// compile with: /EHsc
#include <ppl.h>
#include <array>
#include <sstream>
#include <iostream>
using namespace Concurrency;
using namespace std;
int wmain()
{
// Create an array of integer values.
array<int, 5> values = { 1, 2, 3, 4, 5 };
// Print each value in the array in parallel.
parallel_for_each(values.begin(), values.end(), [](int value) {
wstringstream ss;
ss << value << L' ';
wcout << ss.str();
});
}
Este exemplo produz a saída de exemplo a seguir:
4 5 1 2 3
Porque o parallel_for_each algoritmo atua em cada item em paralelo, a ordem na qual os valores são impressas no console irá variar.
Para obter um exemplo completo que usa o parallel_for_each o algoritmo, consulte Como: Escrever um Loop de parallel_for_each.
go to top
Algoritmo de parallel_invoke
O Concurrency::parallel_invoke algoritmo executa um conjunto de tarefas em paralelo. Ele não retorna até termina de cada tarefa. Esse algoritmo é útil quando você tem várias tarefas independentes que você deseja executar ao mesmo tempo.
O parallel_invoke algoritmo assume como seus parâmetros de uma série de funções de trabalho (funções de lambda, objetos de função ou ponteiros de função). O parallel_invoke algoritmo está sobrecarregado para levar entre dois e dez parâmetros. Cada função que você passa para parallel_invoke deve levar zero parâmetros.
Como outros algoritmos paralelos, parallel_invoke não executar as tarefas em uma ordem específica. O tópico Paralelismo de tarefas (Runtime de simultaneidade) explica como o parallel_invoke algoritmo está relacionado a tarefas e grupos de tarefas.
Exemplo
O exemplo a seguir mostra a estrutura básica da parallel_invoke algoritmo. Este exemplo simultaneamente chama o twice função de três variáveis locais e imprime o resultado no console.
// parallel-invoke-structure.cpp
// compile with: /EHsc
#include <ppl.h>
#include <string>
#include <iostream>
using namespace Concurrency;
using namespace std;
// Returns the result of adding a value to itself.
template <typename T>
T twice(const T& t) {
return t + t;
}
int wmain()
{
// Define several values.
int n = 54;
double d = 5.6;
wstring s = L"Hello";
// Call the twice function on each value concurrently.
parallel_invoke(
[&n] { n = twice(n); },
[&d] { d = twice(d); },
[&s] { s = twice(s); }
);
// Print the values to the console.
wcout << n << L' ' << d << L' ' << s << endl;
}
Esse exemplo produz a seguinte saída.
108 11.2 HelloHello
Para obter exemplos completos que usam o parallel_invoke o algoritmo, consulte Como: Use o parallel_invoke para escrever uma rotina de classificação paralela e Como: Use o parallel_invoke para executar operações paralelas.
go to top
Tópicos relacionados
Como: Escrever um Loop de parallel_for
Mostra como usar o parallel_for o algoritmo para realizar a multiplicação de matriz.Como: Escrever um Loop de parallel_for_each
Mostra como usar o parallel_for_each o algoritmo para calcular a contagem dos números primos um std::array o objeto em paralelo.Como: Use o parallel_invoke para escrever uma rotina de classificação paralela
Mostra como usar o parallel_invoke o algoritmo para melhorar o desempenho do algoritmo de classificação de bitonic.Como: Use o parallel_invoke para executar operações paralelas
Mostra como usar o parallel_invoke o algoritmo para melhorar o desempenho de um programa que executa várias operações em uma fonte de dados compartilhados.Biblioteca paralela de padrões (PPL)
Descreve a PPL, que fornece um modelo de programação imperativo que promove a escalabilidade e facilidade de uso para o desenvolvimento de aplicativos simultâneos.Cancelamento na PPL
Explica a função de cancelamento da PPL, como cancelar o trabalho paralelo e como determinar quando um grupo de tarefas é cancelado.O Runtime de simultaneidade de manipulação de exceção
Explica a função de tratamento de exceção no tempo de execução de simultaneidade.