[zhang pact07] resume

2

Click here to load reader

Upload: marcio-machado-pereira

Post on 04-Jul-2015

124 views

Category:

Technology


1 download

DESCRIPTION

Language and VM Support for fine-grained futures in Java

TRANSCRIPT

Page 1: [Zhang pact07] resume

aug-2011

I. INTRODUÇÃO

o artigo [1], os autores investigaram a implementação de futures no Java J2SE v5.0. Future é uma construção de

linguagem de programação paralela que permite aos programadores especificar computações potencialmente assíncronas. Neste modelo, denominado Executor-Callable-Future, os usuários encapsulam uma computação que pode ser potencialmente avaliada em paralelo usando o objeto Callable e submete este ao objeto Executor. Apesar desta metodologia desacoplar a lógica da aplicação do escalonador de tarefas (thread scheduling), o mesmo impõe uma sobrecarga para os usuários médios além de introduzir um overhead significativo no desempenho.

N

Para endereçar estes problemas, os autores propuseram então Lazy Java Futures, uma implementação do Java Future baseada na técnica originalmente proposta por Mohr e outros denominada Lazy Task Creation (LTC) [2]. Lazy Future primeiramente executa as computações potencialmente concorrentes sequencialmente (inline) e então subdivide as computações através da divisão da pilha de execução (runtime stack) durante o escalonamento e troca das linhas de execução (threads) se a estimativa do sistema sobre o tempo de execução restante da computação Future amortizar o custo da divisão.

Lazy Future segue a abordagem baseada em interface, similar (embora mais eficiente) à Java Futures. Como resultado, esta herda uma semelhante produtividade imposta ao programador e as mesmas limitações de desempenho. Para endereçar estas limitações, os autores proposurem neste artigo uma nova implementação do Java Futures que eles chamaram de Directive-based Lazy Futures (DBLFutures).

DBLFutures extende Lazy Futures para melhorar a facilidade de uso do paralelismo baseado em Java Futures assim como o desempenho e escalabilidade. DBLFutures explora a extensão da linguagem java criada para anotações [3]. As anotações são directivas de código fonte que transmitem informações de metadados do programa para as ferramentas, bibliotecas e as máquinas virtuais Java (JVMs). Estas não

O trabalho em referência foi apresentado na conferência PACT'07 realizado entre os dias 15 e 19 de setembro de 2007 na cidade de Brasov, Romenia. O resumo é parte do trabalho de pesquisa de doutorado do Instituto de Computação da UNICAMP (IC-Unicamp) e foi elaborado por Pereira, M. M. (e-mail: [email protected] ).

afetam diretamente a semântica do programa. Em particular, os autores introduziram a anotação future (denotada @future no código fonte) para variáveis locais. Os usuários usam esta diretiva para anotar variáveis locais que podem ser usadas como resultados (placeholders) de valores retornados por funções que potencialmente podem ser executadas concorrentemente pelo sistema. Se a chamada de uma função armazena seu valor de retorno em uma variável local anotada, ela é identificada como uma future-function call.

O modelo DBLFuture evita a criação (e portanto, a especificação por parte do usuário) de objetos Callable, Future, LazyFuture e outros objetos quando o mesmo é executado sequencialmente (inlined) pelo sistema. Em consequencia, evita-se a alocação de memória, o gerenciamento de memória e a inserção de código fonte extra requerido pelas abordagens anteriores.

II.O ALGORITMO DBLFUTURE

Como primeiro passo do algoritmo, a diretiva future é salva como um atributo do método na representação intermediária (bytecode). O carregador das classes java (class loader) da JVM modificada (DBLFuture-aware JVM) reconhece o atributo e constrói uma tabela de variáveis locais future para cada método, contendo o nome, o índice e a faixa de índices do bytecode de cada variável local future. O compilador dinâmico Just-in-time consulta esta tabela durante a compilação.

Inicialmente, a JVM trata toda future-function call como chamada de função normal e executa o código sequencialmente, na pilha de execução da thread corrente. Para cada chamada desta, o sistema mantém também uma pequena pilha (future stack) com referências para as potenciais chamadas future e um contador que estima a duração da chamada future. O sistema usa esta informação para tomar decisões de divisão e geração de novas linhas de execução (splitting and spawning decisions).

Na figura a seguir, a thread corrente tem 3 chamadas future na sua pilha. Em algum momento, o controller decide que vale a pena gerar a chamada future, com a contagem de amostra 10, para execução paralela. A linha cheia identifica o ponto de divisão da pilha. O divisor (future splitter) então cria uma nova thread para a continuação da future call gerada, copia os frames da pilha abaixo do future frame, que corresponde à thread corrente (chamada de continuation thread), restaura o contexto de execução a partir dos frames

1

Language and Virtual Machine Support for Efficient fine-Grained Futures in Java

Lingli Zhang Chandra Krintz Priya Nagpurkar Computer Science Department

University of California, snta Barbara{lingli_z, ckrintz, priya} @ cs.ucsb.edu

Resumo realizado por Marcio Machado Pereira – RA 780681

Page 2: [Zhang pact07] resume

aug-2011

da pilha corrente, e reinicia a thread corrente no endereço de retorno da future call gerada.

O local do valor de retorno após completar a future call requer um tratamento especial. Se a future call não é dividida, o valor de retorno deve ser armazenado na variável local especificada. Se a future call é dividida e deu origem a uma nova thread, o retorno deve ser armazenado em um espaço reservado (i.e., um objeto future) para o acesso pela continuation thread.

Para saber se a future foi paralelizada, adiciona-se uma palavra chamada split flag para cada frame da pilha de execução. Este flag é um bitmap das future calls geradas (spawned), indexada pelo índice da variável local marcada como future no vetor de variáveis locais do bytecode. A JVM verifica este bit em dois pontos do código: no armazenamento e no primeiro uso do valor de retorno. O modelo suporta até 32 anotações futures (64 em máquinas de 64 bits) por método, podendo ser facilmente extendido.

Similarmente, as instruções que usam o valor de retorno precisam ser expandidas. Se o split flag estiver setado, o código deverá usar o valor de retorno diretamente da pilha no espaço (slot) da variável local. Do contrário, o código deverá executar o método get() do objeto future extraído do mesmo slot, o qual irá bloquear a thread corrente se o valor de retorno não estiver pronto.

Para estimar o tempo de execução de uma future usa-se o serviço de monitoração de desempenho comum na maioria das implementações JVM. Quando o sistema de amostragem (sampling) identifica uma future como de longa duração e há recursos suficientes no processador, o sistema divide a pilha da thread em duas, cria o objeto future e executa a future-function e a thread corrente em paralelo.

III. IMPEMENTAÇÃO E AVALIAÇÃO

Para avaliar o DBLFuture, os autores implementaram o algoritimo no Jikes Research Virtual Machine (JikesRVM). Na média das experimentações, DBLfuture mostrou-se de 2.4 a 2.8 vezes mais eficiente do que o modelo baseado em Lazy Futures. A razão principal para a melhora do desempenho

está no modelo adotado. No modelo Lazy Future, a JVM tem a flexibilidade para decidir se sequencializa (inline) ou gera a thread future (spawn), mas sempre cria os objetos Callable e Future devido ao modelo baseado em interface. DBLFuture, por sua vez, emprega um modelo baseado em chamada de função (function-call) no qual evita-se a criação de objetos Callable completamente e permite que a JVM crie objetos Future somente quando tomar a decisão de dividir a thread, decisão esta baseada na disponibilidade dos recursos e no comportamento dinâmico do sistema.

IV.CONCLUSÃO

Futures provê uma simples e elegante maneira para os programadores introduzirem concorrência nos seus programas. No modelo corrente de Java, os programadores adicionam futures nas suas aplicações usando o modelo Executor-Callable-Future. Este modelo de programação impõe uma sobrecarga para os usuários médios, além de introduzir um overhead significativo no desempenho. Para endereçar estas limitações, os autores introduziram um modelo baseado em anotações (DBLFuture) e apresentaram as extensões necessárias ao compilador Java e à JVM.

Com DBLFuture, os programadores facilmente introduzem paralelismo nas suas aplicações anotando variaveis locais que recebem resultados de chamadas de funções que podem ser executadas com segurança em paralelo. Veja o exemplo da função de Fibonacci abaixo:

public class Fib { public int fib (int n) {

if (n < 3) return n; @future int x = fib (n – 1); int y = fib (n – 2); return x + y;

} ...

}

Note que na implementação proposta, a JVM toma decisões eficientes e automáticas de paralelização de tarefas, no entanto, os usuários ainda são os responsáveis por garantir a segurança (safety) da execução concorrente.

V. REFERENCIAS

[1] L. Zhang, C. Krintz, and S. Soman. Efficient Support of Fine-grained Futures in Java. In International Conference on Parallel and Distributed Computing Systems (PDCS), 2006.

[2] E. Mohr, D. A. Kranz, and J. R. H. Halstead. Lazy task creation: A technique for increasing the granularity of parallel programs. IEEE Trans. Parallel Distrib. Syst., 2(3):264-280, 1991.

[3] JSR-175: A Metadata facility for the JavaTM Programming Language. http://jcp.org/en/jsr/detail?id=175.

2