Integrando Haskell Plataforma NET Dissertao de Mestrado Monique

  • Slides: 42
Download presentation
Integrando Haskell à Plataforma. NET Dissertação de Mestrado Monique Louise de Barros Monteiro Orientador:

Integrando Haskell à Plataforma. NET Dissertação de Mestrado Monique Louise de Barros Monteiro Orientador: André Luís de Medeiros Santos

Motivação Linguagens Funcionais • Altamente produtivas • Base formal Linguagens OO • Largamente utilizadas

Motivação Linguagens Funcionais • Altamente produtivas • Base formal Linguagens OO • Largamente utilizadas • Rico conjunto de APIs • Plataformas de desenvolvimento / execução Integrando Haskell à Plataforma. NET

Agenda ü Plataforma. NET ü Integrando Linguagens Funcionais a. NET ü O Compilador Haskell.

Agenda ü Plataforma. NET ü Integrando Linguagens Funcionais a. NET ü O Compilador Haskell. NET ü Análise de Desempenho ü Conclusões e Trabalhos Futuros Integrando Haskell à Plataforma. NET

Plataforma. NET

Plataforma. NET

Visão Geral “Plataforma multilinguagem de desenvolvimento e execução que permite que diferentes linguagens e

Visão Geral “Plataforma multilinguagem de desenvolvimento e execução que permite que diferentes linguagens e bibliotecas trabalhem juntas, de forma transparente, fácil de construir, gerenciar e integrar com outros sistemas de rede. ” Web Services Web Forms ASP. NET Windows Forms ADO. NET – Dados e XML Biblioteca de Classes Básicas Common Language Runtime Integrando Haskell à Plataforma. NET

CLR • Common Language Runtime • Ambiente de execução da Plataforma. NET • Algumas

CLR • Common Language Runtime • Ambiente de execução da Plataforma. NET • Algumas características: – – – Compilação just-in-time Suporte nativo a delegates e Generics Garbage collector geracional • Implementação da CLI Integrando Haskell à Plataforma. NET

CLI • Common Language Infrastructure • Padrão submetido à ECMA International • Especificação para

CLI • Common Language Infrastructure • Padrão submetido à ECMA International • Especificação para código executável e para o ambiente onde o código será executado • Componentes: – – Metadados Virtual Execution System Common Type System Common Language Specification Integrando Haskell à Plataforma. NET

JVM x CLR Foco em linguagens OO Interoperabilidade entre linguagens Suporte a tail calls

JVM x CLR Foco em linguagens OO Interoperabilidade entre linguagens Suporte a tail calls Suporte a ponteiros para função Integrando Haskell à Plataforma. NET JVM CLR ● ○ ○ ● ● ●

Integrando Linguagens Funcionais a. NET

Integrando Linguagens Funcionais a. NET

Integração – Alternativas • Bridge – Componente intermediador de chamadas entre dois ambientes de

Integração – Alternativas • Bridge – Componente intermediador de chamadas entre dois ambientes de execução – Marshalling / Unmarshalling – Ex. : Hugs. NET • Compilação – Maiores possibilidades de interoperabilidade – Compartilhamento do ambiente de execução Integrando Haskell à Plataforma. NET

Trabalhos Relacionados • Linguagens não estritas – – Hugs. NET Mondrian Haskell → ILX

Trabalhos Relacionados • Linguagens não estritas – – Hugs. NET Mondrian Haskell → ILX Haskell. NET • Linguagens estritas – – F# Nemerle Scheme SML. NET • Implementações para a JVM – Haskell, SML, Scheme Integrando Haskell à Plataforma. NET

O Compilador Haskell. NET

O Compilador Haskell. NET

Arquitetura • Extensão do Glasgow Haskell Compiler (GHC) – Uso do front end e

Arquitetura • Extensão do Glasgow Haskell Compiler (GHC) – Uso do front end e das otimizações aplicadas pelo GHC • Tradução de STG (Shared Term Graph Language) para CIL (Common Intermediate Language, ou “IL”), assembly da CLR – Linguagem funcional simplificada • Ambiente de Execução (“runtime system”) • Geração de código verificável Integrando Haskell à Plataforma. NET

GHC – Arquitetura Integrando Haskell à Plataforma. NET

GHC – Arquitetura Integrando Haskell à Plataforma. NET

Estratégia de Compilação • Uniões Discriminadas • Closures • Ambiente de execução – Versão

Estratégia de Compilação • Uniões Discriminadas • Closures • Ambiente de execução – Versão 1 – Versão 2 • Aplicação de Funções • Controle da Pilha de Chamadas Integrando Haskell à Plataforma. NET

Uniões Discriminadas data List t = Nil | Cons t (List t) • List

Uniões Discriminadas data List t = Nil | Cons t (List t) • List é uma união discriminada. • Nil e Cons são construtores. • Construtores – Alternativas de Representação: – Uma classe por construtor (Ex. : F#, Mondrian) – Compartilhamento de classes • Casamento de padrão – Alternativas de Representação: – Uso de instrução switch – Uso de instruções para identificação da classe (Ex. : F#, Mondrian) • Alternativa adotada: compartilhamento de classes + switch Integrando Haskell à Plataforma. NET

Uniões Discriminadas • Casamento de padrão: switch (scrutinee. tag) { case 1: . .

Uniões Discriminadas • Casamento de padrão: switch (scrutinee. tag) { case 1: . . . case 2: Pack 2<Closure, Closure> k = (Pack 2<Closure, Closure>) scrutinee; Closure arg_1 = k. arg 1; Closure arg_2 = k. arg 2; . . . } • Aplicação de construtores: new Pack(1); new Pack_2<Closure, Closure>(2, x, xs); Integrando Haskell à Plataforma. NET

Closures • Objetos alocados dinamicamente que encapsulam um código a ser executado e um

Closures • Objetos alocados dinamicamente que encapsulam um código a ser executado e um ambiente que pode ser acessado pelo código. f : : Int -> u -> (Int -> Int) f x y = let g w = x + w in g • g é uma closure que encapsula um código que espera receber um argumento e acessa um argumento recebido por f. • x é uma variável livre em g. • f é uma closure sem variáveis livres. • Em linguagens lazy, argumentos e variáveis livres são closures. Integrando Haskell à Plataforma. NET

Closures • Alternativas de Representação: – Uma classe por closure • Grande número de

Closures • Alternativas de Representação: – Uma classe por closure • Grande número de classes • Ex. : F#, Mondrian, implementações para JVM – Classes genéricas para vários tipos de closure • Uso de ponteiro para método – náo verificável • Uso de delegates • Alternativa adotada: classes genéricas com uso de delegates Integrando Haskell à Plataforma. NET

Delegate • Objeto que encapsula: – um ponteiro para um método a ser invocado

Delegate • Objeto que encapsula: – um ponteiro para um método a ser invocado – uma referência para o objeto alvo no qual o método deverá ser chamado (null para método estáticos) • Instância de uma classe que herda de Multicast. Delegate Implementação da CLI Integrando Haskell à Plataforma. NET

Ambiente de Execução 1 Integrando Haskell à Plataforma. NET

Ambiente de Execução 1 Integrando Haskell à Plataforma. NET

Ambiente de Execução 2 Integrando Haskell à Plataforma. NET

Ambiente de Execução 2 Integrando Haskell à Plataforma. NET

Aplicação de Funções • Aplicação de funções desconhecidas estaticamente ou aplicações parciais • Modelo

Aplicação de Funções • Aplicação de funções desconhecidas estaticamente ou aplicações parciais • Modelo push/enter (Ex. : Mondrian) – Código da função chamada a aplica ao número correto de argumentos – Fast entry point – Slow entry point • Modelo eval/apply (Ex. : F#, Bigloo for Scheme) – Função chamadora aplica a função chamada ao número correto de argumentos • Alternativa adotada: modelo push/enter – Maior facilidade de implementação Integrando Haskell à Plataforma. NET

Pilha de Chamadas • Pilha de chamadas tende a um crescimento muito rápido •

Pilha de Chamadas • Pilha de chamadas tende a um crescimento muito rápido • Possíveis soluções: – Tail-calls (prefixo suportado pela IL -. tail) – Trampolim while (f != null) f = f. Invoke(); – Instrução jmp (não verificável) Integrando Haskell à Plataforma. NET

Exemplo • Função map Integrando Haskell à Plataforma. NET

Exemplo • Função map Integrando Haskell à Plataforma. NET

Exemplo 1 public static IClosure map( IClosure f, IClosure l) { 2 Pack scrutinee

Exemplo 1 public static IClosure map( IClosure f, IClosure l) { 2 Pack scrutinee = (Pack) l. Enter(); 3 switch (scrutinee. tag) { Alocação e 4 case 1: return new Pack(1); inicialização de 5 case 2: closures 6 Pack 2<Closure, Closure>k = 7 (Pack 2<Closure, Closure>) scrutinee; 7 Closure arg 1 = k. arg 1; Closure arg 2 = k. arg 2; 9 Updatable_2_FV<Closure, Closure>fx_closure = 10 new Updatable_2_FV<Closure, IClosure>( 11 new Upd. Clo. Function<Closure, IClosure>(fx)); 11 fx closure. fv 1 = arg 1; fx closure. fv 2 = f; 12 Updatable_2_FV<Closure, Closure>fxs closure = 13 new Updatable_2_FV<Closure, Closure>( 14 new Upd. Clo. Function<Closure, IClosure>((fxs)); 14 fxs closure. fv 1 = f; fxs closure. fv 2 = arg 2; 15 return new Pack 2<IClosure, IClosure>(2, fx closure, fxs closure); 16 } 17 } 19 public static Closure fx(Updatable_2_FV<Closure, Closure> closure){ Chamada ao 20 Runtime. System. Push(closure. fv 1); slow entry 21 return <tail> closure. fv 2. Enter(); point 22 } 23 public static Closure fxs(Updatable_2_FV<Closure, Closure> closure){ 24 return <tail>map(closure. fv 1, closure. fv 2); Chamada ao 25 } fast entry point Integrando Haskell à Plataforma. NET

Análise de Desempenho e Otimizações

Análise de Desempenho e Otimizações

Metodologia • Subconjunto do grupo Imaginário do benchmark Nofib • Execuções consecutivas (6) dos

Metodologia • Subconjunto do grupo Imaginário do benchmark Nofib • Execuções consecutivas (6) dos programas – Tempo de execução em segundos (comando time) – Média aritmética • Valores de comparação sumarizados por média geométrica Integrando Haskell à Plataforma. NET

Entradas • Dificuldade para escolha de entradas – Nofib sugere saídas – Dados desatualizados

Entradas • Dificuldade para escolha de entradas – Nofib sugere saídas – Dados desatualizados Programa Digits_e 1 2000 Digits_e 2 3000 Exp 3 • Escolha baseada em tempos de execução razoáveis (testes críticos) 9 Primes 4500 Queens 13 Tak Integrando Haskell à Plataforma. NET Entrada (12, 1, 25) Wheel-sieve 1 400000 Wheel-sieve 2 80000

Uso de Delegates Programa Closures como delegates Closures separadas de delegates Melhora Digits_e 1

Uso de Delegates Programa Closures como delegates Closures separadas de delegates Melhora Digits_e 1 32, 06 29, 30 8, 6% Digits_e 2 33, 63 32, 42 3, 6% Exp 3 29, 13 39, 44 -35, 4% Primes 20, 30 21, 10 -3, 9% Queens 18, 38 16, 72 9, 0% Tak 14, 54 14, 59 0, 0% Wheel-sieve 1 19, 80 11, 62 41, 3% Wheel-sieve 2 291, 78 18, 76 93, 6% Média Integrando Haskell à Plataforma. NET 32, 6%

Principais Otimizações • Remoção do update frame • Compartilhamento de booleanos • Relacionadas a

Principais Otimizações • Remoção do update frame • Compartilhamento de booleanos • Relacionadas a tail-calls Integrando Haskell à Plataforma. NET

Remoção do Update Frame • Remoção da pilha de atualizações • Uso do próprio

Remoção do Update Frame • Remoção da pilha de atualizações • Uso do próprio stack frame da CLR • 1ª. versão do ambiente de execução Programa Digits_e 1 (1000) Antes 12, 43 11, 99 3, 6% Digits_e 2 (1500) 11, 68 10, 31 11, 8% 3, 97 2, 77 30, 2% 13, 33 12, 73 4, 5% 9, 30 8, 98 3, 5% Exp 3 Primes (3000) Queens (12) Média Integrando Haskell à Plataforma. NET Depois Melhora 11, 4%

Booleanos – Compartilhamento Programa Digits_e 1 (1500) Antes 18, 78 16, 31 13, 1%

Booleanos – Compartilhamento Programa Digits_e 1 (1500) Antes 18, 78 16, 31 13, 1% Digits_e 2 (2000) 15, 93 12, 81 19, 6% Exp 3 40, 02 40, 06 0. 0% Primes (3500) 18, 63 12, 84 31, 1% Queens 38, 80 23, 12 40, 4% Tak 41, 60 22, 32 46, 3% Wheel-sieve 1 (200000) 11, 95 8, 42 29, 6% 9, 94 7, 11 28, 5% Wheel-sieve 2 (40000) Média Integrando Haskell à Plataforma. NET Depois Melhora 27, 3%

Tail-calls • Remoção de tail-calls apenas do ambiente de execução Programa Digits_e 1 (1500)

Tail-calls • Remoção de tail-calls apenas do ambiente de execução Programa Digits_e 1 (1500) Antes Depois Melhora 16, 30 15, 99 1, 9% Digits_e 2 (2000) 12, 84 12, 51 2, 5% Exp 3 40, 11 39, 03 2, 7% Primes (3500) 12, 83 12, 41 3, 3% Queens 23, 14 22, 86 1, 2% Tak 22, 34 22, 29 0, 2% Wheel-sieve 1 (200000) 8, 43 5, 69 32, 6% Wheel-sieve 2 (40000) 7, 11 7, 01 1, 5% Média Integrando Haskell à Plataforma. NET 6, 4%

Tail-calls • Impacto da presença de tail-calls no código compilado Programa Digits_e 1 Com

Tail-calls • Impacto da presença de tail-calls no código compilado Programa Digits_e 1 Com tail-calls Sem tail-calls Melhora 29, 44 33, 58 12, 3% Digits_e 2 (2000) 12, 62 13, 39 5, 7% Exp 3 39, 41 41, 59 5, 2% Primes 21, 14 22, 52 6, 1% Queens 22, 92 36, 88 51, 1% Tak 22, 37 17, 37 -28, 8% Wheel-sieve 1 (200000) 5, 69 Estouro da pilha Wheel-sieve 2 (40000) 7, 08 8, 82 Média Integrando Haskell à Plataforma. NET 19, 8% 13, 2%

Tail-calls • Substituição por instruções de desvio Programa Digits_e 1 Antes 29, 46 29,

Tail-calls • Substituição por instruções de desvio Programa Digits_e 1 Antes 29, 46 29, 30 0, 5% Digits_e 2 32, 47 32, 42 0, 2% Exp 3 39, 49 39, 44 0, 1% Primes 21, 15 21, 10 0, 2% Queens 22, 92 16, 72 22, 0% Tak 22, 39 14, 59 34, 9% Wheel-sieve 1 15, 01 11, 62 22, 6% Wheel-sieve 2 18, 77 18, 76 19, 8% Média Integrando Haskell à Plataforma. NET Depois Melhora 11, 9%

Haskell. NET X GHC Nativo Programa Digits_e 1 GHC Nativo Haskell. NET Razão. NET/Nativo

Haskell. NET X GHC Nativo Programa Digits_e 1 GHC Nativo Haskell. NET Razão. NET/Nativo 6, 29 29, 30 4, 7 Digits_e 2 6, 69 32, 42 4, 8 Exp 3 2, 81 39, 44 14, 0 Primes 0, 95 21, 10 22, 1 Queens 10, 21 16, 72 1, 6 Tak 13, 22 14, 59 1, 1 Wheel-sieve 1 6, 78 11, 62 1, 7 Wheel-sieve 2 5, 91 18, 76 3, 2 Média Integrando Haskell à Plataforma. NET 4, 0

Conclusões e Trabalhos Futuros

Conclusões e Trabalhos Futuros

Contribuições • Desenvolvimento de uma implementação de Haskell para. NET • Avaliação de desempenho

Contribuições • Desenvolvimento de uma implementação de Haskell para. NET • Avaliação de desempenho sob vários aspectos • Ambiente de estudo e prototipação de técnicas alternativas • Base para a interoperabilidade com outras linguagens Integrando Haskell à Plataforma. NET

Conclusões • Parte do prelúdio implementada – Subconjunto básico implementado em C# • Desenvolvimento

Conclusões • Parte do prelúdio implementada – Subconjunto básico implementado em C# • Desenvolvimento e avaliação de dois ambientes de execução – Segunda versão: maior portabilidade e manutenibilidade • Desempenho da mesma ordem de magnitude que o GHC nativo para a maioria dos programas • Gerenciamento de memória ainda é um fator crítico • Análises de desempenho fornecem uma visão realista da CLR Integrando Haskell à Plataforma. NET

Trabalhos Futuros • Suporte a mais Bibliotecas • Análises de Desempenho – Outras representações

Trabalhos Futuros • Suporte a mais Bibliotecas • Análises de Desempenho – Outras representações para closures – Avaliação do modelo eval/apply – Extensões à máquina virtual (via Rotor) • Integração com Phoenix • Suporte a interoperabilidade – – – Implementação da FFI (Foreign Function Interface) Extensões OO à inguagem Geração de wrappers Integrando Haskell à Plataforma. NET

Integrando Haskell à Plataforma. NET Dissertação de Mestrado Monique Louise de Barros Monteiro Orientador:

Integrando Haskell à Plataforma. NET Dissertação de Mestrado Monique Louise de Barros Monteiro Orientador: André Luís de Medeiros Santos