Programação Paralela com DryadLINQ
Olá pessoal, tudo certo?
Depois de um post do Otávio na semana passada, acabei dando uma circulada pelos projetos da Microsoft Research e encontrei algo bem legal!
Para quem não viu, o Otávio falou rapidamente sobre MapReducing, uma estratégia interessante para a divisão de tarefas no processamento paralelo, que é bem aderente para uma série de cenários com demanda de alta performance, como em pesquisas científicas e simulações.
Usando as palavras do Otávio, “…a idéia é simples: se quisermos aumentar o paralelismo de uma operação, um processo Mestre deve dividir a tarefa em diversas partições, uma para cada processo Trabalhador. Chamamos este passo de Map. Em seguida, cada processo retorna seu resultado parcial para o processo Mestre, que aglutina e retorna todas as respostas para quem requisitou o processamento. Chamamos este passo de Reduce…”
O post original continua a explicação sobre o tema e como podemos aplicar a estratégia sobre o Windows Azure, um ambiente de alta escalabilidade e armazenamento de dados ilimitado. Tipos como Web Roles, Worker Roles, Queues e Tables permitem uma implementação suave desse tipo de abordagem para uma computação de alto desempenho.
Na Microsoft Research, encontrei o projeto DryadLINQ, que é um ambiente de programação para a construção de aplicações paralelas de alta escalabilidade de dados, rodando sobre clusters de PC. Como descrito pelo time da Research, o objetivo do projeto é tornar a computação paralela simples o suficiente para projetos do dia-a-dia.
O desenho abaixo ilustra a arquitetura do projeto DryadLINQ, veja:
DryadLINQ …pronuncia-se [dr’aied link] :)
Ref.: https://research.microsoft.com/en-us/projects/dryadLINQ/
Já está disponível uma versão acadêmica para testes, assim como uma documentação em .PDF bem completa. A partir desta documentação, retirei a listagem abaixo, onde vemos a referência para a biblioteca LinqToDryad e o código para a listagem de conteúdo de um arquivo texto (só para ilustrar).
1: using System;
2: using System.Collections.Generic;
3: using System.Linq;
4: using System.Text;
5: using LinqToDryad;
6:
7: public static class Program
8: {
9: static void ShowOnConsole<T>(IQueryable<T> data)
10: {
11: foreach (T r in data)
12: Console.WriteLine("{0}", r);
13: }
14: static void Main(string[] args)
15: {
16: string basedirectory = @"file://\\machine\directory";
17: string filename = "inputfile.txt";
18: DryadDataContext ddc = new DryadDataContext(basedirectory);
19: DryadTable<LineRecord> table = ddc.GetTable<LineRecord>(filename);
20: ShowOnConsole(table);
21: Console.ReadKey();
22: }
23: }
Para conferir a versão já disponívei e alguns exemplos em DryadLINQ, veja:
Dryad and DryadLINQ: Academic Release
Ref.: https://connect.microsoft.com/site/sitehome.aspx?SiteID=891
Some sample programs written in DryadLINQ
Ref.: https://research.microsoft.com/pubs/66811/tr-2008-74.pdf
A programação paralela envolve diversos desafios, assim como abordagens específicas para seu tratamento.
Porém, temos visto muito de sua aplicação restrita em ambientes de pesquisa e universidades. Creio que iniciativas como o DryadLINQ e mesmo técnicas como o MapReducing sobre ambientes de computação na nuvem devem trazer a programação paralela para mais perto das iniciativas comerciais num futuro próximo. O próprio .NET 4.0 está chegando com alguns recursos importantes para programação paralela, como o Task Parallel Library (TPL), o Parallel LINQ (PLINQ), o Coordination Data Structures (CDS), além de melhorias na System.Threading. Cada um desses recursos deve merecer um post dedicado no futuro.
Olhando um pouco o Parallel LINQ (PLINQ), ele permite aos desenvolvedores aproveitarem os múltiplos núcleos de uma máquina multicore, através do modelo de programação do LINQ.
Veja abaixo um exemplo de código com PLINQ, onde notamos o uso da cláusula .AsParallel(), que ativa o aproveitamento multicore disponível na máquina:
1: var q = from p in people.AsParallel()
2: where p.Name == queryInfo.Name &&
3: p.State == queryInfo.State &&
4: p.Year >= yearStart &&
5: p.Year <= yearEnd
6: orderby p.Year ascending
7: select p;
Um assunto puxa o outro e as oportunidades são imensas.
Por enquanto é só! Até o próximo post :)
Waldemir.