BT

Disseminando conhecimento e inovação em desenvolvimento de software corporativo.

Contribuir

Tópicos

Escolha a região

Início Notícias O que o .NET 4.0 Beta 1 vai trazer para o PLINQ?

O que o .NET 4.0 Beta 1 vai trazer para o PLINQ?

Ed Essey, um Gerente de Software no time Microsoft Parallel Computing, escreveu sobre as últimas melhorias para o PLINQ que irão aparecer no .NET 4.0 Beta 1 que será liberado logo. Algumas delas são: Padrão de Operadores “With“, Modo de Execução, Cancelamento, Refatoração, Melhorias de Performance.

A lista completa das melhorias do PLINQ no Beta 1 segue abaixo:

  • Padrão de Operadores “With”
  • Modo de Execução
  • Cancelamento
  • Particionamento Personalizado
  • Refatoração
  • Opções de Mesclagem
  • AsMerged renomeado devolta para AsSequential
  • Operadores binários agora necessitam de AsParallel em ambos os lados
  • Refatoração
  • Removido operadores usados raramente

Padrão de Operadores “With”. Existem 4 novos métodos:

  • e.AsParallel().WithDegreeOfParallelism
  • e.AsParallel().WithExecutionMode
  • e.AsParallel().WithCancellation
  • e.AsParallel().WithMergeOptions

Modo de Execução. O PLINQ foi regulado para consumir recursos similares a consulta LINQ-to-Objects, especialmente relacionados com consumo de memória. Quando uma chamada PLINQ vai consumir muito mais recursos, a chamada é executada sequencialmente e não em paralelo. A decisão de mudar uma execução sequencial foi feita baseado na forma da consulta. Essas são as consultas que são executadas sequencialmente:

  • Consultas que contenham Selects indexados, Wheres indexados, SelectMany indexados, ou ElementAt em uma posição onde os índices não estão mais na ordem original. A ordenação do índice é sensível a operadores que mudam a ordenação (ex. OrderBy) e operadores que removem elementos (ex. Where).
  • Consultas que contenham os operadores Take, TakeWhile, Skip, SkipWhile quando os índices não estão na ordem original (conforme acima).
  • Consultas que contenham Zip, SequenceEquals, a menos que um dos data sources (fontes de dados) tenha a ordem indexada originalmente e outro data source é indexável (i.e. um array ou IList).
  • Consultas que contenham Concat ou Reverse, a menos que seja aplicado a um data source indexável.

Para forçar a executação em paralelo pode ser usado:

e.AsParallel().WithExecutionMode(ParallelExecutionMode.ForceParallelism)

Cancelamento. Operações paralelas podem ser canceladas como esse exemplo mostra:

var cts = new CancellationTokenSource();

var q = a.AsParallel().WithCancellation(cts.Token).Where(x=>Filter(x)).Select(x=>DoWork(x);

-- thread separada --

foreach (var e in q) { … }  // declaração 1

-- thread separada --

var l = q.ToList(); // declaração 2

-- thread separada --

cts.Cancel(); // isso irá tentar cancelar qualquer consulta em execução,

// incluindo as declarações 1 e 2

Particionamento Personalizado. As classes Partitioner, OrderablePartitioner e a factory class Partitioner oferecem controle em como os dados são particionados.

Refactoração. As interfaces IParallelEnumerable/em>, IParallelEnumerable e IParallelOrderedEnumerable não são mais interfaces, e sim classes abstratas que não podem ser extendidas: ParalellQuery, ParalellQuery e OrderedParallelQuery. A razão é que eles não eram para ser extendidos inicialmente.

Opções de Mesclagem. “A manipulação de ParallelMergeOptions foi movida de AsMerged.  O Merge buffering agora é especificado via o método  WithMergeOptions.”

AsMerged. O AsMerged foi renomeado para AsSequential por semelhança com AsParallel no modo de ser usado.

Operadores Binários. Os operadores LINQ com 2 data sources precisam de AsParallel em ambos os lados. As operações como:

a.AsParallel().AsOrdered().Zip(b, (x, y) => x*y);

são paralelizadas como:

a.AsParallel().AsOrdered().Zip(b.AsParallel(), (x, y) => x*y);

ou

a.AsParallel().AsOrdered().Zip(b.AsParallel().AsOrdered(), (x, y) => x*y);

Operadores afetados: Zip, Join, GroupJoin, Concat, SequenceEqual, Union, Intersect, Except.

Melhorias de Performance.

1. Mesclagem de pipelines com preservação da ordenação –antes, só colocando o AsOrdered em uma consulta forçava uma consulta inteira a ser executada antes que um elemento retornasse por yield.  Agora isso está otimizado para que os elementos da consulta possam dar yield conforme eles forem sendo produzidos com valores Default (AutoBuffered) e NotBuffered do MergeOptions.

2. Igualmente aperfeiçoado o particionamento para data sources que não implementam o IList

3. Melhor performance de algumas consultas sobre IList ou arrays

4. Regulagem do tamanho dos particionamentos por pedaços (Chunk) - Particionamento por pedaços é o esquema de particionamento mais comum para consultas sobre data sources diferentes de IList e arrays (i.e. data sources não indexáveis). O tamanho dos pedaços agora crescem tanto quanto os pedaços são acessados. Isso é para balancear entre casos como a) consulta com pequeno conjunto de dados, mas delegates caros e b) consultas com grande quantidade de dados mas com delegates baratos.

5. Remoção de semelhanças falsas em casos de compartilhamento, o que aumento em 6x a performance em alguns casos.

Removido operadores usados raramente. Alguns operadores que foram criados por razão de performance, mas não oferecem nenhum performance em cima do LINQ foram removidos. Não foi especificado quais operadores foram removidos.

Avalie esse artigo

Relevância
Estilo/Redação

Conteúdo educacional

BT