UM PROCESSADOR JAVA VLIW COM BAIXO CONSUMO DE POTÊNCIA PARA SISTEMAS EMBARCADOS Antonio C. S. Beck F., Luigi Carro Instituto de Informática – Universidade Federal do Rio Grande do Sul, Porto Alegre, Brasil {caco,carro}@inf.ufrgs.br SUMMARY This paper presents a low power architecture of a Java processor specific for the embedded system domain. We show that, thanks to the specific stack architecture and to the use of the VLIW technique, one is able to obtain an aggressive reduction of power dissipation, with small area overhead. The underlying technique is based on the reuse of memory access instructions, hence reducing these accesses. The architecture is validated for some complex embedded applications like IMDCT computation and other synthetic benchmarks. Besides, this processor is compared to other processors with the same instruction set architecture concerning power, area and performance. UM PROCESSADOR JAVA VLIW COM BAIXO CONSUMO DE POTÊNCIA PARA SISTEMAS EMBARCADOS Antonio C. S. Beck F., Luigi Carro Instituto de Informática – Universidade Federal do Rio Grande do Sul, Porto Alegre, Brasil {caco,carro}@inf.ufrgs.br ABSTRACT Este artigo apresenta uma arquitetura VLIW de um processador Java, direcionada para baixo consumo de potência para ser usada em sistemas embarcados. Nós mostramos que, graças ao método computacional particular da arquitetura de pilha e ao uso da técnica VLIW, uma grande redução de potência pode ser obtida, com um pequeno incremento de área. Em conjunto com esta técnica, uma outra é aplicada, baseada na reutilização de acessos à memória, que traz uma conseqüente diminuição destes acessos, reduzindo ainda mais o consumo de energia. As arquiteturas são validadas com algumas aplicações complexas como IMDCT e outros benchmarks sintéticos, voltados para o domínio dos sistemas embarcados. Além do mais, este processador é comparado com outros processadores da mesma família, levando em conta desempenho, área e potência. 1. INTRODUÇÃO Como se pode observar cotidianamente, devido à evolução tecnológica, usam-se cada vez mais sistemas computacionais para facilitar nossas tarefas do dia-a-dia. Estes sistemas são utilizados para diferentes propósitos, como entretenimento, comunicação, controle de eletrodomésticos e veículos, entre vários outros. Estes sistemas são classificados como sistemas computacionais embarcados. Exemplos práticos de utilização destes sistemas são fornos de microondas, videogames, impressoras, mp3 players, câmeras fotográficas digitais, telefones celulares. Neste mesmo caminho, enquanto a tecnologia permite acrescentar mais e mais transistores dentro de um CI (circuito integrado), pesquisadores direcionam seus esforços para achar a melhor maneira para a utilização desta grande capacidade computacional. Conforme o SIA (Semiconductor Industry Association) Roadmap [1], a quantidade de transistores que poderão ser integrados em uma pastilha de silício chegará, em um futuro não muito distante, a um bilhão. Em computadores pessoais, por exemplo, a nova tecnologia é aplicada em várias técnicas para o aumento de performance, tanto para atender ao usuário comum com aplicações de escritório e entretenimento, quanto às grandes companhias, que utilizam este poder computacional para fazer previsão de tempo, simulações subatômicas ou de tráfego de veículos. Todavia, em sistemas embarcados, não é correto apenas ter o tempo de computação como principal métrica. Principalmente em sistemas embarcados portáteis, tem-se que haver uma preocupação equivalente com o consumo de energia, já que geralmente estes sistemas são dependentes de uma bateria. Além disto, aspectos como custo e tempo de produção têm enorme impacto na eletrônica de consumo. Para aplicações embarcadas, a tendência é fazer uso da tecnologia não para alcançar a máxima performance possível, mas sim, a performance necessária para atender somente aos requisitos da aplicação, economizando-se em potência. Somando-se a esse fato, observa-se que os sistemas embarcados estão agregando cada vez mais funções, oferecendo ao usuário diversos recursos antes inexistentes. Por exemplo, telefones celulares de última geração reúnem funções como acesso a Internet, visor colorido, reprodução de áudio e vídeo, conexão de dados via infravermelho, entre outros [2]. Em paralelo a isto, empresas estão cada vez mais preocupadas em reduzir o tempo do ciclo de projeto de seus produtos. Em contrapartida, elas precisam melhorar a qualidade destes: seja agregando novas funções, melhorando a interface com o usuário, ou ainda aumentando a vida útil da bateria. Esta meta fica quase inatingível quando considerada a complexidade de projeto que atualmente estes sistemas requerem. Devido a isto, várias metodologias têm sido pesquisadas, como em [3] e [4], assim como arquiteturas para sistemas embarcados [5]. Esta crescente complexidade exige que os sistemas sejam projetados em um alto nível de abstração. Em algum momento do projeto, esta especificação em alto nível deverá ser mapeada diretamente para o sistema final, que é um conjunto de hardware e software. Assim, é necessária a automatização do projeto, através do uso de ferramentas EDA (Eletronic Design Automation), para fazer com que estas descrições em um alto nível sejam automaticamente transformadas para o hardware real. Contudo, é necessário tomar decisões, mesmo em um alto nível de abstração, que terão impacto direto no desempenho, potência e custo do sistema final. É em todo este paradigma, da programação em um alto nível de abstração para reduzir o tempo do ciclo de projeto, do uso de ferramentas automatizadas, e de restrições de performance, área e potência, que a linguagem Java é inserida. A linguagem Java facilita a modelagem, programação e validação do sistema, já que é baseada em objetos. Assim, todo sistema pode ser previamente modelado usando uma linguagem específica, como a Linguagem Unificada para Modelagem (Unified Modelling Language ou UML) [6]. Além de tudo, Java tem a vantagem de ser multiplataforma: o sistema como um todo pode ser executado e validado previamente em outra plataforma de desenvolvimento, e depois portado para a plataforma alvo. Somando-se a isso, a linguagem possui outras vantagens para ser aplicada em sistemas embarcados: facilita e agiliza o desenvolvimento do produto, pois já é uma linguagem amplamente difundida e utilizada, e além do mais, oferece segurança e pequeno tamanho ocupado na memória de instruções, já que Java foi originalmente desenvolvido para ser transmitido pela Internet e é baseada em máquinas CISC. São por estas e outras razões que a linguagem Java está se tornando cada vez mais popular em ambientes embarcados, que por sua vez, estão em franca expansão [7]. É estimado que o número de dispositivos com Java embarcado como telefones celulares, PDA (Personal Digital Assistent) e pagers irá crescer de 176 milhões em 2001 para 721 milhões em 2005 [8]. Não obstante, é previsto que no mínimo 80% dos telefones celulares irão suportar Java em 2006 [9]. Ainda, há previsões da industria que haverá dez vezes mais desenvolvedores para sistemas embarcados em relação a desenvolvedores de software de propósito geral no ano de 2010 [10]. Conclui-se então que é estritamente necessário analisar cuidadosamente sistemas embarcados baseados em Java. Contudo, a própria natureza da linguagem Java não é voltada para performance, e sim para a portabilidade. Então, otimizações tanto no código quanto na microarquitetura de processadores Java devem ser feitas levando em consideração também o quesito potência. Neste artigo é mostrado um estudo sobre diferentes arquiteturas capazes de executar bytecodes Java e são discutidos os requerimentos de área, performance e principalmente potência, focando sempre em aplicações para sistemas embarcados. Nós demonstramos que com o uso da técnica VLIW (Very Long Instruction Word) [23], pode-se otimizar a execução de instruções e obter uma drástica redução em potência, em um fator de aproximadamente 25 vezes, comparando com a nossa arquitetura Java mais simples. Além do mais, é demonstrado que o uso da técnica de VLIW, além do incremento da performance, beneficia-se de arquiteturas baseadas em pilha e reduz a dissipação de potência devido à redução de acessos na memória, uma das maiores causas de consumo de energia em sistemas embarcados [11,12,13]. Além disso, as técnicas apresentadas podem ser utilizadas em outras áreas, como compiladores Java e máquinas virtuais. Nossos experimentos são validados através de simulações, usando diferentes versões de nosso processador Java, e executando diferentes algoritmos usados no domínio dos sistemas embarcados. A área ocupada pelos processadores é computada em número de células lógicas de um FPGA, através da síntese em VHDL destes processadores. Este artigo é organizado da seguinte maneira: a seção 2 mostra uma breve revisão dos processadores Java e VLIW existentes. Na seção 3 são discutidas as diferentes arquiteturas das máquinas Java que serão estudadas, e é apresentada a vantagem do uso do VLIW em máquinas de pilha. Seção 4 apresenta o ambiente de simulação: o simulador de potência e os algoritmos executados nos processadores. A seção 5 mostra os resultados dos processadores em termos de potência, área e performance. Na ultima seção são mostradas as conclusões e introduzidos trabalhos futuros. 2. REVISÃO BIBLIOGRÁFICA Um grande número de processadores Java específicos para o mercado de sistemas embarcados já foi proposto. O Picojava I, da Sun [14], um processador com quatro estágios de pipeline, e o Picojava II [15], são provavelmente os mais estudados. Apesar da especificação destes processadores permitir um tamanho variável das memórias cache de instruções e de dados, e a unidade de ponto flutuante ser opcional, não há nenhum cuidado especial na microarquitetura para reduzir a área e consumo de potência do sistema. O mesmo ocorre com outros processadores Java: Komodo [16], um microcontrolador Java que tem como principal finalidade aplicações de tempo real; e Traja [17], um processador com pipeline que faz reordenação das instruções para evitar dependência de dados. No domínio dos processadores VLIW, em [18] e [19] foram propostos processadores de pilha baseados em VLIW para um sistema de rede para transmissão multimídia em tempo real e processamento de dados. Além disso, a Sun propôs a arquitetura MAJC [20], que explora o paralelismo em vários níveis: instrução, dados, threads e processos, através de multithreading especulativa e vertical, multiprocessadores em um chip e VLIW. Dentre todos os processadores citados anteriormente, em nenhum, quando da construção da microarquitetura, se teve a preocupação de se aplicar técnicas para a redução de potência, assim como otimizações nos bytecodes Java com o mesmo propósito. Além do mais, suas microarquiteturas não são totalmente parametrizáveis, mostrando uma preocupação secundária com a área do sistema, tendo em vista somente a performance como preocupação principal. Neste caminho, a pesquisa de processadores Java com baixo consumo de potência, capazes de manter a performance suficiente para executar a aplicação alvo com o mínimo de dissipação de energia, é o objetivo deste trabalho. 3.2. Femtojava Low-Power A versão Femtojava Low-Power [22] possui um pipeline de cinco estágios: busca de instruções, decodificação, busca de operandos, execução e escrita de resultados, como pode ser observado na figura 2. Uma das principais características deste processador é a implementação da pilha de operandos (operand stack) e do depósito de variáveis locais do método em um banco de registradores, ao invés de usar a memória principal para estes propósitos, como é feito no Femtojava multiciclo. + 0 MUX 1 MAR Output Ports IMM MUX Data Bus Intruction Bus Prg Mem Address Bus Input Ports Data Mem Address Bus A ROM Const +/SP FRM MUX 3. ARQUITETURAS DOS PROCESSADORES JAVA VAR Timer A ALU 3.1. Femtojava Multiciclo O processador FemtoJava [21] é um microcontrolador baseado em operações de pilha e que executa bytecodes Java. Características do Femtojava são o conjunto reduzido de instruções, arquitetura Harvard, pequeno tamanho e facilidade de inserção e remoção de instruções. Este processador foi projetado especificamente para a utilização em sistemas embarcados. Possui algumas características interessantes, como o tamanho da parte de controle ser diretamente proporcional ao número de instruções utilizadas. Isto é, a partir de uma ferramenta disponível chamada Sashimi [21], o bytecode Java gerado é analisado e a parte de controle irá suportar apenas aquelas instruções que são utilizadas pela aplicação. A primeira arquitetura estudada foi o Femtojava Multiciclo [21], que leva de 3 a 14 ciclos para executar uma instrução, dependendo de sua complexidade. Instruções aritméticas levam 4 ciclos, já chamadas e retornos de métodos, 14 ciclos. Sua microarquitetura pode ser observada na figura 1. MUX PC RAM B Interrupt Handler IR Control Figura 1 – Femtojava Multiciclo [21] BI D BO EX ER Figura 2 – Femtojava Low-Power [22] O primeiro estágio, de busca de instruções, é composto por uma fila de instruções com nove registradores de 1 byte cada. A primeira instrução da fila é mandada para o estágio de decodificação. Este estágio tem três funções: geração da palavra de controle para a instrução, verificação de dependência de dados e informar ao controlador da fila de instruções o tamanho da instrução corrente, com o objetivo de colocar a próxima instrução do fluxo no primeiro lugar da fila. Isto é necessário porque as instruções têm comprimento variável: podem ter nenhum, um ou dois operandos imediatos. Quando no mínimo 4 registradores da fila de instrução estão vazios, uma palavra de 32 bits é buscada da memória de instruções, tomando como base o valor do registrador PC (program counter). A busca de operandos (terceiro estágio) é feita em um banco de registradores de tamanho variável, definido a priori em estágios anteriores do ciclo de projeto, através de simulação. Como já citado anteriormente, a pilha e o depósito das variáveis locais do método estão disponíveis no banco de registradores. A pilha e o depósito de variáveis locais são encontrados no mesmo banco de registradores para facilitar a chamada e retorno de métodos, tirando vantagem da especificação da JVM (Java Virtual Machine), onde cada método é localizado por um apontador de quadro (frame) na pilha. Há dois registradores usados neste estágio: SP e VARS. Eles apontam para o topo da pilha e para o início do depósito de variáveis, respectivamente. Dependendo da instrução, um deles é usado como base para a busca de operandos. Depois desta busca, os operandos são mandados para o quarto estágio, onde eles serão executados. Não há predição de desvio, com o objetivo de economizar em área. Todos os desvios são considerados previamente como não verdadeiros. Caso o desvio seja verdadeiro, uma penalidade de três ciclos é paga. O quinto estágio é responsável por salvar, se necessário, o resultado do estágio de execução no banco de registradores, usando o SP ou o VARS como base. Como o banco de registradores não pode ser lido e escrito simultaneamente, quando uma instrução no quinto estágio grava o seu resultado e uma outra instrução no terceiro estágio precisa buscar algum operando, uma bolha é inserida no pipeline. O processador Femtojava Low-Power faz uso da técnica de forwarding [23]: Se há uma instrução no estágio de execução que irá escrever o seu resultado no banco de registradores (pilha ou variável local) no próximo ciclo, e a próxima instrução do fluxo precisa acessar o banco de registradores para buscar algum operando que faça parte do resultado da instrução anterior, uma dependência verdadeira (RAW – Read After Write, ou leitura depois de uma escrita) é caracterizada. Uma das soluções é parar o pipeline, inserindo bolhas, até a primeira instrução passar pelo estágio de escrita dos resultados. Outra solução é fazer uso da técnica de forwarding, passando diretamente o resultado do estágio de execução para o estágio de busca de operandos. Dois tipos de forwarding podem ocorrer: quando uma instrução no estágio de execução consome um operando do topo da pilha (como a instrução istore, que grava o topo da pilha em algum lugar do depósito de variáveis locais); ou quando alguma instrução consome dois operandos da pilha (como em operações aritméticas: iadd, isub, ior). No primeiro caso, o operando repassado vai do estágio de execução (quarto estágio) para o estágio de busca de operandos. No segundo caso, o segundo operando necessário vem do ultimo estágio, de escrita dos resultados. Especificamente em processadores de pilha, o uso desta técnica traz uma vantagem quando comparada com processadores RISC: ao contrário destes, em instruções que manipulam a pilha, os operandos repassados através de forwarding para estágios anteriores do pipeline não são usados mais no futuro. Como conseqüência, não há necessidade de gravar o resultado destas instruções no banco de registradores. Isto resulta em uma grande redução no consumo de potência, porque o número de escritas na pilha é reduzido. Em [24] mostramos um ganho de 8 vezes comparando a arquitetura sem e com forwarding com um incremento mínimo de área. 3.3. Femtojava VLIW O processador Femtojava VLIW é basicamente uma extensão do Femtojava Low-Power, com suas unidades funcionais e decodificadores de instrução replicados. Os decodificadores adicionais não suportam as instruções de chamada e retorno de métodos, já que as instruções responsáveis por isso estão sempre no fluxo principal. O depósito de variáveis locais encontra-se apenas no primeiro banco de registradores. Quando instruções de outros fluxos precisam ler ou escrever algum valor de uma variável local do método, elas precisam buscar de lá. Cada fluxo de instrução tem seu próprio banco de registradores para a pilha de operandos, que por sua vez possuem menos registradores que o banco principal, já que a pilha de operandos destes fluxos secundários não crescem tanto quanto a principal. A palavra VLIW tem um tamanho variável, evitando acessos desnecessários à memória. Um cabeçalho na primeira instrução da palavra informa para o controlador de busca de instruções quantas instruções a palavra corrente possui. A busca por paralelismo em um programa Java é feito diretamente nos bytecodes. O algoritmo funciona da seguinte maneira: todas as instruções que dependem do resultado da anterior são agrupadas em um bloco de operações. Todo o programa Java é dividido em grupos como este. Estes grupos podem ser paralelizados respeitando o número de unidades funcionais existentes. Por exemplo, se há apenas um multiplicador, duas instruções que usam esta unidade funcional não podem ficar em paralelo. Um exemplo deste procedimento é apresentado na figura 3. (a) (b) Figura 3 – Processo de formação da palavra VLIW No exemplo, na figura 3b, a primeira instrução imul (multiplicação) irá consumir os operandos empilhados previamente pelos dois bipush (bipush 10 e bipush 5). Depois disso, a instrução ishl (deslocamento para esquerda) irá consumir outros dois operandos empilhados pelos próximos bipush (bipush 3 e bipush 4). Depois, a instrução iadd (soma) irá consumir os resultados de imul e ishl. Finalmente, a instrução istore irá salvar o resultado da instrução iadd no depósito de variáveis locais. Como há uma relação entre todas estas instruções, isto é, umas usam os resultados das operações das outras, elas formam um bloco de operação. Outro bloco de operação é formado pelas duas ultimas instruções bipush (bipush 7 e bipush 8) e imul, já que estas instruções dependem entre si e não utilizam nenhum resultado das instruções do bloco anterior. Em outras palavras, a pilha de operandos destes dois blocos são independentes. Conseqüentemente, eles podem ser paralalelizados, como pode ser observado na figura 5b. É importante perceber que as duas instruções imul não podem ficar na mesma palavra, já que estamos considerando que nosso processador VLIW possui apenas um multiplicador. Como mencionado anteriormente, uma das maiores causas de consumo de energia são os acessos à memória. Assim, outra otimização nos bytecodes Java foi feita preocupando-se com este problema. Depois da busca por paralelismo, outra busca é feita: instruções que lêem a memória principal (getstatic) são alinhadas na mesma palavra VLIW. Isto só ocorre se elas buscam o valor no mesmo endereço e entre estas duas instruções de busca na memória este valor não muda, isto é, não há escrita neste endereço de memória. Conseqüentemente, com as instruções alinhadas, apenas um getstatic é executado, passando diretamente o seu resultado para os outros que estão na mesma palavra, economizando assim potência decorrente dos outros getstatics que não precisaram ser executados. A figura 6 ilustra o procedimento. Figura 4 – Processo de alinhamento dos acessos à memória 4. AMBIENTE DE SIMULAÇÃO 4.1 CACO-PS CACO-PS [22] é um simulador de potência configurável, de código compilado e ciclo-a-ciclo, que foi utilizado para prover dados sobre o consumo de energia, utilização de memória e performance dos processadores. A dissipação de potência é baseada na atividade de chaveamento. Como os processadores têm memórias separadas para instruções e dados, também foi incluso um módulo para medir as memórias RAM e ROM. Assim, pode-se verificar a potência relativa consumida pela CPU, memória de instruções e memória de dados. É importante medir o impacto de cada um destes blocos, para melhor explorar o espaço de projeto. A descrição de uma arquitetura no simulador é baseada na técnica de componentes, onde um componente pode ter qualquer nível de abstração. Todos os processadores foram descritos na sintaxe do simulador usando componentes nos mais diversos níveis de abstração. Para fazer a estimativa de potência, a taxa de chaveamento de cada componente é coletada. Conseqüentemente, pode-se estimar a potência dinâmica de cada componente, com dados relativos em número de capacitância de gates chaveadas por componente. Esta técnica é comparável com técnicas baseadas em componente como em [25,26]. 4.2. Algoritmos Utilizados Cinco diferentes tipos de algoritmos foram implementados e simulados nas arquiteturas descritas na seção 3. Cálculo do seno, bastante utilizado em bibliotecas aritméticas; ordenação e busca, usados em agendas; IMDCT (Inverse Modified Discrete Cosine Transformation), uma importante parte do algoritmo de descompressão de MP3; e uma biblioteca que emula somas de ponto flutuante, já que o processador Femtojava não possui uma unidade de ponto flutuante para economizar em área. Dois diferentes algoritmos de busca são utilizados. O primeiro faz uma pesquisa seqüencial em um vetor ordenado. O segundo faz uma pesquisa binária neste mesmo vetor. Os algoritmos de ordenação arranjam um conjunto de 10 números os colocando em ordem crescente. Três diferentes tipos de ordenação são feitos: usando bubblesort, selectsort e insertsort. Já a emulação de soma de pontos flutuantes faz 20 somas de dois números em ponto flutuante e coloca os resultados em um vetor na memória. Finalmente, o algoritmo de cálculo de seno utiliza o método cordic para calcular o resultado. Três diferentes versões de laços desenrolados (loop unrolled) também foram feitas para a versão IMDCT. 5. RESULTADOS A tabela 1 mostra a área ocupada pelas três diferentes versões do processador Femtojava. É importante ressaltar que o banco de registradores, utilizado como pilha de operandos e depósito de variáveis locais do método, tem 32 registradores, que é o máximo requerido entre todas as aplicações (note que eles estão sendo contados na tabela, apesar de que a memória do FPGA poderia ter sido usada para este propósito). A área computada também inclui a unidade de controle que suporta todas as instruções do conjunto do Femtojava. Os dados de área foram tirados através do VHDL de cada versão usando o programa Leonardo Spectrum [17], e são apresentados em números de células lógicas. Tabela 1 – Área ocupada pelas versões em VHDL dos processadores, em células lógicas PROCESSADOR MULTICICLO PIPELINE Area (LCs) 1365 3220 VLIW (n° de instruções por palavra) 2 4077 4 5347 8 7887 A tabela 2 mostra a performance de cada algoritmo em cada arquitetura, em número de ciclos. Em alguns algoritmos sendo executados na versão VLIW, o resultado em número de ciclos é o mesmo. Isto acontece porque mesmo tendo mais instruções por palavra disponível para a paralalelização, o limite já foi alcançado mesmo com menos instruções. Tabela 2 – Performance das arquiteturas, em número de ciclos Algoritmo Multiciclo Seno Ord./Bubble Ord./Select Ord./Insert Busca Binária Busca Sequencial IMDCT IMDCT u1 IMDCT u2 IMDCT u3 Soma ponto flutuante 2447 6950 5335 5111 1162 diferentes Número de Ciclos VLIW Pipeline 2 4 755 599 592 2424 2104 1967 1930 1707 1670 1934 1601 1331 403 368 365 Figura 5 – Potência consumida por ciclo no núcleo 8 583 1967 1670 1331 365 7586 140300 97354 92882 51345 1997 40306 31500 30369 18858 1775 33050 19325 18689 12789 1775 32994 12313 11737 8929 1775 32994 9944 9432 7741 30747 14531 12474 12313 12313 Como podem ser observados na tabela 2, melhores resultados são alcançados quando usadas versões com laços desenrolados (IMDCT u1, IMDCT u2 e IMDCT u3). A razão é a diminuição de desvios condicionais, que é uma das maiores vantagens das versões desenroladas, que tem como principal desvantagem o aumento no tamanho do programa, e conseqüentemente, da memória de instruções. Reduzindo o número de desvios condicionais, reduz-se o número de ciclos pagos por laços que são verdadeiros (3 ciclos no caso do Femtojava, que sempre considera que a condição de um laço não é verdadeira). Para a versão VLIW, a grande vantagem do uso da versão desenrolada é que ela expõe mais o paralelismo no nível dos bytecodes para o analisador, já que o tamanho dos blocos básicos aumenta significativamente. Operando na mesma freqüência, as arquiteturas VLIW são as que possuem um maior consumo de energia por ciclo no núcleo, já que ela são as mais complexas, com mais unidades funcionais e registradores. Este comportamento pode ser observado na figura 5 (onde VLIW 2 significa 2 instruções por palavra e assim por diante). Apesar da potência consumida por ciclo nas arquiteturas VLIW serem maiores que nas arquiteturas Multiciclo e Low-Power, a energia total consumida pelo sistema é menor, por causa do aumento da média de IPC (Instruction per Cycle, ou instruções por ciclo) executadas e também pelo decremento no número de acessos à memória. Figura 6 – Total de energia gasta no núcleo A versão Multiciclo usa a memória principal como pilha de operandos e depósito de variáveis locais do método. Há uma grande diferença em termos de consumo de energia entre esta arquitetura e a Low-Power, com pipeline. Esta, por sua vez, somente acessa a memória em chamadas e retorno de métodos ou em instruções específicas, como getstatic e putstatic. A figura 6 mostra a vantagem de implementar a pilha de operandos e o depósito de variáveis em um banco de registrador no núcleo ao invés de usar a memória principal. Figura 8 – Economia de memória em VLIW quando utilizado o alinhamento de getstatic Figura 7 – Total de energia gasta com acessos à memória Agora, na figura 8, mostra-se a vantagem quando usando a técnica VLIW com e sem alinhamento de getstatic, como já foi explicado na seção 3. Nota-se uma expressiva redução em alguns algoritmos, principalmente no filtro IMDCT. É importante notar que há uma pequena perda de paralelismo quando utilizada esta técnica já que algumas instruções são deslocadas para os gestatic ficarem alinhados na mesma palavra. Esta perda fica em média, entre os algoritmos analisados, de 1,5% Como já foi demonstrado, passando da arquitetura Multiciclo para a Low-Power, e da Low-Power para VLIW, vantagens tanto de economia de potência no núcleo quanto aos acessos à memória RAM são obtidas. Mostra-se na figura 9 o consumo total de energia (considerando núcleo, RAM e ROM) entre todas as arquiteturas utilizadas. A diferença de consumo entre a versão Multiciclo e Low-Power tem duas razões principais: o uso do banco de registradores no núcleo e a diminuição de escritas na pilha devido ao uso da técnica de forwarding. Já a melhora apresentada pelo VLIW se resume basicamente a utilização de bancos de registradores menores da pilha de operandos usados pelos fluxos secundários, ao invés de usar sempre o banco principal, de maior tamanho. Figura 9 – Energia total consumida pelos algoritmos nas diferentes versões Em aplicações embarcadas, muitas delas com requerimentos de tempo real, um desempenho específico precisa ser garantido para determinada aplicação. Assumindo que este desempenho já é alcançado pela versão Multiciclo, então a freqüência de operação pode ser reduzida nas versões Low-Power e VLIW com o objetivo de economizar ainda mais potência, já que estas arquiteturas podem alcançar uma média maior de instruções por ciclo, como já mostrado na tabela 1. Assim, assumindo que a potência dinâmica é a dominante dentro da potência total consumida pelo sistema, e que todos os gates do processador foram uma capacitância de chaveamento coletiva, com uma taxa de chaveamento em comum chamada de f, então: (1) Como pode ser observado em [27], a tensão de funcionamento do processador Transmeta TM5400 (conhecido como Crusoe) [28], desenvolvido para sistemas embarcados, pode diminuir em um fator de 4,6% a cada 10% de redução da freqüência de operação. As figuras 10 e 11 mostram a redução relativa em consumo de energia quando a freqüência das versões Low-Power e VLIW são reduzidas para alcançar exatamente a mesma performance da versão Multiciclo. Conseqüentemente, também há uma redução de voltagem, tomando como base a equação em (1). Finalmente, nós mostramos a vantagem de aumentar a área do processador para suportar o pipeline, banco de registradores interno e VLIW, trocando área por uma enorme economia em termos de potência. A figura 12 mostra a comparação relativa entre o aumento de área e a média de potência consumida por todas as aplicações. Figura 12 – Analisando área e potência entre o Multiciclo e a versão Low-Power Figura 10 – Energia total consumida pelo Multiciclo e Low-Power considerando que possuem o mesmo desempenho Como pode ser observado, com um pouco menos de 3 vezes de incremento de área, em média um fator de 25 vezes é obtido em termos de redução de energia. 7. CONCLUSÕES E TRABALHOS FUTUROS Figura 11 – Energia total consumida pela LowPower e versões VLIW considerando que todas possuem o mesmo desempenho É importante ressaltar que as versões IMDCT com loop unrolled são as mais beneficiadas, já que devido ao uso desta técnica um alto grau de paralelismo é alcançado, trazendo uma alta taxa de instruções executadas por ciclo. Sendo assim, a freqüência e a tensão podem ser diminuídas ainda mais quando comparados com outros algoritmos. Nós demonstramos que para aplicações embarcados, é possível obter uma grande redução no consumo de potência com proporcionalmente um pequeno incremento na área total. Particularmente para máquinas de pilha, o uso de pipeline, da pilha sendo implementada em um banco de registradores e da técnica VLIW, trazem uma grande redução em termos de consumo de potência. Para versões com laços desenrolados, o VLIW traz resultados promissores, pois há uma maior exposição do paralelismo. Assim, para trabalhos futuros, nós pretendemos estudar outras alternativas para aumentar a performance do VLIW, como o uso da técnica de software pipelining para expor ainda mais o paralelismo entre os bytecodes. Além disso, outros algoritmos bastante usados em sistemas embarcados estão sendo construídos e serão estudados. 7. REFERÊNCIAS BIBLIOGRÁFICAS [1] Semiconductor Industry Association Home Page. Disponível em: http://public.itrs.net/files/1999_SIA_Roadmap/Home.htm. [2] Nokia Home Page. Disponível em: http://www.nokia.com. [3] S. Edwards, L. Lavagno, E. A. Lee, A. SangiovanniVincentelli, “Design of Embedded Systems: Formal Models, Validation, and Synthesis”. Proceedings of the IEEE, NewYork, v.85, n.3, Mar. 1997, p.366-390 [4] A. Sangiovanni-Vincentelli, G. Martin, “Plataform-Based Design and Software Design Metodology for Embedded Systems”. IEEE Design & Test, vol. 18, no. 6, pp. 23-33, NovDec. 2001. [5] M. Jacome, G. Veciana, “Design Challenges for New Application-Specific Processors”. IEEE Design & Test, vol. 17, no. 2, Apr-June. 2000, pp. 40-50 [6] Rational Software Corporation. Unified Modeling Language. Notation Guide. Version 1.0, Santa Clara, 1997. Disponível em: <http://www.rational.com>. [7] M. Schlett, “Trends in Embedded-Microprocessor Design”. Computer, vol. 31, no. 8, 1998, pp. 44–49 [8] D. Takahashi, Java Chips Make a Comeback, Red Herring, 2001 [9] G. Lawton, “Moving Java into Mobile Phones”, Computer, vol. 35, n. 6, 2002, pp. 17-20 [18] K. Nakamura, K. Sakai, T. Ae, “Real-Time Multimedia Data Processing using VLIW Hardware Stack Processor”, Proceedings IEEE Workshop on Parallel and Distributed RealTime Systems, 1995, pp. 84-89 [19] T. Ae, K. Nishimura, R. Aibara, K. Sakai, K. Nakamura, “Real-Time Multimedia Network System Using VLIW Hardware Stack Processor”, Proceedings IEEE Workshop on Parallel and Distributed Real-Time Systems, 1995, pp. 84-89 [20] M. Tremblay, J. Chan, S. Chaudhry, A. Conigliaro, S. Tse, “The MAJC Architecture: A Synthesis of Parallelism and Scalability”. IEEE Micro, vol. 20, n. 6, 2000, pp. 12-25 [21] S.A. Ito, L. Carro, R.P. Jacobi, “Making Java Work for Microcontroller Applications”, IEEE Design & Test of Computers, vol. 18, n. 5, 2001, pp. 100-110 [22] A.C.S. Beck F., J.C.B. Mattos, F.R. Wagner, L. Carro, “CACO-PS: A General Purpose Cycle-Accurate Configurable Power-Simulator”, 16th Brazilian Symp. Integrated Circuit Design (SBCCI 2003), Sep. 2003 [10] R.W. Atherton, “Moving Java to the Factory”. IEEE Spectrum, 1998, pp. 18-23, [23] J. L. Hennessy, D. A. Patterson, Computer Architecture: A Quantitative Approach, Morgan Kaufmann Publishers, 3th edition, 2003 [11] V. Tiwari, S. Malik, A. Wolfe, “Power Analysis of Embedded Software: A First Step Towards Software Power Minimization”, IEEE Transactions on VLSI Systems, vol. 2, n. 4, Dec. 1994, pp. 437–445 [24] A. C. Beck F., L. Carro, "Low Power Java Processor for Embedded Applications". VLSI-SOC 2003 - IFIP 12th International Conference on Very Large Scale Integration, Germany, December, 2003 [12] T. Simunic, G. Micheli, L. Benini, “Energy-Efficient Design of Battery-Powered Embedded Systems”, Proceedings of the International Symposium on Low Power Electronics and Design (ISLPED99), Aug. 1999 [25] V. Dalal, C. P. Ravikumar, "Software Power Optimizations in an Embedded System". VLSI Design Conference, IEEE Computer Science Press, Jan. 2001, pp. 254-259 [13] G. Chen, R. Shetty, M. Kandemir, N. Vijaykrishnan, M. Irwin, “Tuning garbage collection for reducing memory system energy in an embedded java environment”, ACM Transactions on Embedded Computing Systems, vol. 1, n. 1, Nov. 2002, pp. 27-55 [14] J. M. O’Connor, M. Tremblat, “Picojava-I: the Java Virtual Machine in Hardware”, IEEE Micro, vol. 17, n. 2, Mar-Apr. 1997, pp. 45-53 [15] Sun Microsystems. PicoJava-II Microarchitecture Guide. Mar. 1999 [16] J. Kreuzinger, R. Marston, Th. Ungerer, U. Brinkschulte, C. Krakowski, “The Komodo Project: Thread-based Event Handling Supported by a Multithreaded Java Microcontroller”, 25th Euromicro Conference (EUROMICRO), Sep. 1999, pp. 2122-2128 [17] N. Shimizu, M. Naito, “A Dual Issue Queued Pipelined Java Processor TRAJA-Toward an Open Source Processor Project”. Proceedings of Asia Pacific Conference on ASIC (APASIC), 1999, pp. 213-216 [26] R. Chen, M. J. Irwin, R. Bajwa, “Architecture-Level Power Estimation and Design Experiments”. ACM Transactions on Design Automation of Electronic Systems, vol. 6, n. 1, Jan. 2001, pp 50-66 [27] J. Pouwelse, K. Langendown, H. Sips, “Dynamic Voltage Scaling on a Low-Power Microprocessor”, The Seventh Annual International Conference on Mobile Computing and Networking, 2001, pp. 251-259 [28] Transmeta Corporation, Tm5400 processor specifications, http://www.transmeta.com [29] Leonardo Spectrum, http://www.mentor.com/synthesis Disponível em: