Abordagens para projeto low-power (1/3)

iphone-battery

1 Eficiência

Na última publicação sugeri que a Compaq teria percebido a portabilidade como requisito mais que desejável para a computação pessoal. Apesar de os primeiros computadores da companhia terem ~12 kg (!) e serem considerados “portáteis” simplesmente por serem apresentados em uma maleta com alças, ainda precisavam de uma tomada de corrente para funcionar.

Um pouco mais tarde, com a popularização das tecnologias multimídias e dos PDAs (personal digital assistants, ou “palmtops”), a computação portátil começa a precisar de cada vez mais performance, e aí a otimização de consumo passou a ser critério determinante em um projeto. O objetivo é ser eficiente: realizando tanto ou mais trabalho com menos energia, as baterias duram mais. Não sei dizer exatamente quando e nem quem começou as pesquisas no assunto, mas um dos trabalhos acadêmicos mais relevantes na área é datado de 1992 (Low-power CMOS Digital Design, CHANDRAKASAN et. al).

Nesta publicação quero falar um pouco sobre técnicas de baixo consumo e a oportunidade de aplicá-las nas diferentes fases e camadas de abstração de um projeto. Aqui estou assumindo que os circuitos são essencialmente digitais. O projeto low-power para circuitos (integrados) analógicos tem técnicas distintas que podem ser assunto para outra postagem.

2 Consumo estático e dinâmico

Dois componentes gerais de consumo são o consumo estático e o consumo dinâmico. Este refere-se ao consumo ocasionado pelas transições de uma porta lógica e é proporcional à corrente circulante, à frequência de transições e às capacitâncias que são carregadas e descarregadas nessas transições. O consumo estático se refere às correntes que circulam entre Vdd e Gnd mesmo quando os módulos de um dispositivo estão desligados. Com os comprimentos de canais dos transistores cada vez menores, as correntes de leakage passaram a ser uma significativa parcela do consumo total, quando não a componente dominante. Quanto menor o canal de um transistor, menor será a sua tensão de threshold e menor será a diferença entre a corrente de operação e a corrente de leakage. Na verdade, a corrente de leakage aumenta exponencialmente com a diminuição da tensão de threshold.

De maneira geral, para um gate lógico:

Potência total = Potência dinâmica + Potência estática [W]

Potência dinamica = Vdd^2 * Freq * Cl* p [W]

onde p é a probabilidade de uma transição lógica ocorrer.

3 Níveis de abstração de um projeto digital

Fazendo uma analogia com carros, uma Lamborghini Diablo 1991 é um sistema igual a um Renault Clio 2010. Ambos são automóveis, do tipo “carro”, compostos por carroceria, 4 rodas, motor, diferencial, volante, transmissão e etc. Porém arquiteturalmente são projetos radicalmente distintos.

Um sistema é concebido para prover uma solução. No caso dos automóveis o problema a ser resolvido é como deslocar algo de um lugar a outro. Se eu preciso levar uma pessoa de um ponto ao outro, eu posso escolher construir um carro, uma moto ou um patinete (que não é um automóvel!). Enfim, as escolhas em nível de sistema, são aquelas que irão definir o que é o meu projeto e quais são suas características. Estas escolhas terão como ponto de partida os requisitos do produto. Se o propósito é deslocar até 5 pessoas de um ponto ao outro e com economia de energia, o Clio faz muito mais sentido que a Lamborghini, se o requisito for um carro.

De maneira geral, podemos representar a estrutura de um projeto, nos seguintes níveis de abstração:

Nível de Sistema: refere-se a definição do conjunto de módulos de um projeto e suas conexões (microprocessador+RAM+NVM+I/O, etc.)

Nivel Arquitetural: refere-se a forma como são construído os módulos definidos no sistema e como eles interagem: a definição de interfaces, dos protocolos de controle, comunicação, etc. (ex.: microprocessador RISC-V 32-bit, 8KB de RAM, 64KB de memória NAND Flash, transreceptor compatível com NFC, camada MAC comunica-se com a PHY através de uma interface AMBA-PB, etc.)

Nível de Registradores (Register Transfer Level): representação do circuito digital como um conjunto de registros, ULAs, Muxes, contadores, etc. Pode ser chamado de “microarquitetura”.

Nível lógico: mapeamento do RTL como um conjunto de portas lógicas, latches e flip-flops.

Nível de Circuito: a representação elétrica do sistema, através de um esquemático de transistores e outros componentes elétricos.

4 Abordagens low-power no nível de sistema

Quando pensamos em sistemas digitais o consumo geralmente estará relacionado à área e performance. Uma maior performance exige uma operação em alta freqüência e com suficiente força de drive. A área relaciona-secom o tamanho dos dispositivos que por sua vez dita o tamanho das capacitâncias a serem carregadas/descarregadas.

4.1 Faça um SoC

O advento dos SoCs, sistemas inteiramente construídos em um único circuito integrado, possibilitou drástico aumento na eficiência energética. Se falamos de um sistema que está construído na forma de chips e componentes discretos conectados em uma placa, a transformação em SoC pode ser vista como uma técnica para redução de consumo. E das mais eficientes.

4.2 Capriche no co-projeto de hardware+software

O que implementar em hardware e o que implementar em software? Tipicamente as implementações em hardware consumirão menos energia que as suas contrapartes em software.

Podemos simplesmente identificar aquelas rotinas que consomem mais processamento e escolher implementá-las em hardware.

Entretanto em um fluxo de projeto que realmente aproveite a oportunidade de se poder implementar qualquer parte de um sistema em hardware ou software, uma abordagem baseada em modelos deve ser considerada. Existem linguagens como o SystemC ou SystemVerilog que permite a confecção de modelos em alto nível de abstração. Outras ferramentas como SystemVue, Matlab/Simulink são dedicadas a modelar sistemas. Depois de o sistema modelado, as simulações são utilizadas para fazer estimativas da performance e consumo das funcionalidades, e pode-se fazer escolhas direcionadas sobre o que será implementado em hardware ou software. As funcionalidades que consomem mais recursos beneficiarão todo o sistema se forem construídas com arquitetura visando baixo consumo. Ou seja, as análises no nível do sistema guiam nossas escolhas arquiteturais mais adiante.

A validação da arquitetura pode ser feita através de uma abordagem TLM (Transaction-Level Modeling).

lowpower_hwswcodesignflow

4.3 Software eficiente

Idealmente o seu compilador deve conseguir produzir um código objeto otimizado, mas ele não tem nenhuma outra informação a não ser o código que você entrega a ele, puro e duro. Compiladores “system aware” só amanhã.

Quantas instruções tem a task mais executada do sistema? Quantos ciclos de clock cada instrução consome? Se um sistema rodando a 5 MHz acorda o processador a cada segundo para executar 500 instruções, admitindo 1 instrução/ciclo, ao diminuírmos somente uma instrução desta task, estaremos dando uma sobrevida a bateria de ~ 6,5 segundos por ano, num sistema 24/7. Escalone isso para mais MHz de operação e mais instruções economizadas, e veja por si só.

Assim, o nosso código, como regra geral deve evitar primitivas complexas e ser otimizado em desempenho. Considero que conhecer o processador e o compilador, e a utilização de boas práticas de engenharia de software como a refatoração, são as melhores forma de escrever códigos eficientes. Abaixo alguns exemplos:

Código original

Código otimizado

if ((i % 10) == 0 )
{
   // faça algo
}
i++;
If (counter == 10)
{
   // faça algo
   counter=0;
}
else
{ 
   i ++
}
counter++;

A operação ‘módulo’ usualmente toma mais ciclos de instrução. É mais econômico reproduzir o mesmo efeito com operações mais baratas.

Código original

Código otimizado

for(i=0;i<10;i++)
{
   // faça algo 1
}
for(i=0;i<10;i++)
{
   // faça algo 2
}
for(i=0;i<10;i++)
{
   // faça algo 1
   // faça algo 2
}

Uma chamada de loop com inicialização, incremento e comparação é economizada.

Código original

Código otimizado

unsigned int x;
 for (x = 0; x < 100; x++)
 {
     A[x] = B[x];
 }
unsigned int x; 
 for (x = 0; x < 100; x += 5 )
 {
     A[x]   = B[x];
     A[x+1] = B[x+1];
     A[x+2] = B[x+2];
     A[x+3] = B[x+3];
     A[x+4] = B[x+4];
     
 }

No código acima, 100 elementos do vetor A serão copiados para as primeiras 100 posições do vetor B. A segunda implementação faz com que o loop precise ser rodado 20 vezes, ao invés de 100.

(Link externo: este AN da Atmel indica no capítulo 9 algumas formas de otimizar tamanho e tempo de execução para AVRs 8-bit)


 

Na parte 2 vou falar sobre técnicas aplicadas no nível arquitetural (power-gating, clock gating, multi Vdd, multi Vth, DVFS…).

Até mais!

O texto desta publicação é original. As seguintes fontes foram consultadas:
The Art of Hardware Architecture, Mohit Ahora
Ultra-Low Power Integrated Circuit Design, Niaxiong Nick Tan et al.

Autor: Antonio Giacomelli de Oliveira

Engenheiro Eletrônico

Deixe uma Resposta

Preencha os seus detalhes abaixo ou clique num ícone para iniciar sessão:

Logótipo da WordPress.com

Está a comentar usando a sua conta WordPress.com Terminar Sessão /  Alterar )

Google photo

Está a comentar usando a sua conta Google Terminar Sessão /  Alterar )

Imagem do Twitter

Está a comentar usando a sua conta Twitter Terminar Sessão /  Alterar )

Facebook photo

Está a comentar usando a sua conta Facebook Terminar Sessão /  Alterar )

Connecting to %s