Testing Raspberry Pi DVS

Visão Geral

Uma maneira comum de economizar energia em computadores é explorando a capacidade de alteração da frequência da CPU. O Raspberry Pi utiliza um processador ARM1176JZF-S e, segundo a documentação online da ARM, esta CPU pode ser executada em qualquer frequência abaixo da máxima suportada pelo processador. Para permitir qualquer frequência, a arquitetura ARM11 emula um DVS (Dynamic Voltage Scaling) contínuo em um processador discreto. Isso é realizado mantendo a tensão no nível máximo e, então, alternando o relógio do sistema entre a frequência máxima e o estado desligado.

Para aplicar isso, o Intelligent Energy Management (IEM) — tecnologia que roda no processador ARM para classificar os tipos de atividade e analisar os padrões de uso para predição global da performance futura exigida pelo sistema — define quadros diretamente relacionados ao nível de desempenho. Na Figura 1, o desempenho exigido no primeiro quadro é de 50%, então a CPU trabalha em frequência máxima por metade do quadro e depois é desligada no restante. No segundo quadro, a exigência é de 25% da CPU, e no último, 75%.

Implementação ARM de DVS contínuo, Autor [Figura 1]

Testando o DVS Contínuo

Para testar a capacidade DVS do Raspberry Pi, dois experimentos foram configurados. O primeiro consistiu em verificar o efeito de diferentes frequências no tempo de execução da CPU para uma aplicação. O segundo experimento foi sobre o consumo de energia. Todos os testes foram feitos usando o Arch Linux ARM. Para mudar a frequência, o comando cpufreq-set foi executado. Aqui está um exemplo de como usar este comando:

cpufreq-set -f 0.2 GHz

Nesse caso, 0.200 é a frequência desejada em GHz e -f define a nova frequência.

Desempenho da CPU Segundo a Frequência Selecionada

Para testar o efeito da emulação DVS contínua num sistema como o Raspberry Pi, um código cuja execução dependia apenas da CPU foi executado e o tempo gasto pela CPU foi medido. O código utilizado neste experimento foi:

int main(int argc, char *argv[])
{
  int limit;

  if (argc == 0) {
    printf("%d", argc);
    printf("1 argument\n");
    return(0);
  } else {
    limit = atoi(argv[1]);
  }
  
  int i;
  struct timespec startCpuTime, stopCpuTime, startTotalTime, stopTotalTime;

  clock_gettime(CLOCK_THREAD_CPUTIME_ID, &startCpuTime);

  for(i=0; i<limit; i++) {
    log(2*i) + exp(i) + pow(2,i)*i;
  }

  clock_gettime(CLOCK_THREAD_CPUTIME_ID, &stopCpuTime);

  double cpuUsedTime = ((double) (stopCpuTime.tv_sec - startCpuTime.tv_sec)
    - (stopCpuTime.tv_nsec - startCpuTime.tv_nsec) 
    / (double) 1000000000L);
    
  double totalUsedTime = ((double) (stopTotalTime.tv_sec - startTotalTime.tv_sec)
    - (stopTotalTime.tv_nsec - startTotalTime.tv_nsec)
    / (double) 1000000000L);
    
  printf("Tempo de CPU = %g e tempo total da aplicacao = %g \n", cpuUsedTime, totalUsedTime);
  return 0;
}

O código acima pode ser encontrado no repositório [4]. É um código muito simples, consistindo basicamente na execução de um loop for enquanto i é menor que limit, e o tempo de execução é medido utilizando a função clock_gettime() da biblioteca time.h. Para obter o tempo exato de uso interno da CPU, o clock_gettime() usa o parâmetro CLOCK_THREAD_CPUTIME_ID. Para compilar o programa, o GCC foi usado com as flags -lrt (necessária para o clock_gettime()) e -lm (devido às funções matemáticas). Executando o código acima e variando a frequência em passos de 0.1GHz num intervalo de 0.2GHz a 0.7GHz, o tempo de execução da CPU foi medido e plotado na Figura 2.

Mostra a quantidade de tempo gasta pela CPU para executar o programa de teste[Figura 2].

Consumo de Energia de Acordo com a Escala de Frequência e Tensão

Para realizar um experimento para verificar o consumo de energia de acordo com a frequência, um multímetro Tenma 72-9380A foi usado e o Raspberry Pi foi alimentado via interface GPIO. Nos experimentos, as frequências de: 0.1GHz, 0.2GHz, 0.4GHz, 0.6GHz, 0.8GHz e 1GHz foram usadas. Para medir o consumo de energia, a aplicação acima foi executada por cerca de 10s e o consumo médio de energia foi usado para plotar o gráfico na Figura 3. Como esperado, o consumo de energia aumentou proporcionalmente de acordo com a frequência com um comportamento expresso por $\alpha f^3$.

Mostra o consumo de energia do Raspberry Pi de acordo com a frequência selecionada.[Figura 3]

É importante notar que entre os intervalos de frequências 0.2GHz-0.6GHz, 0.6GHz-0.8GHz e 0.8GHz-1GHz, a linha de consumo muda sua taxa de aumento em relação ao intervalo anterior, com exceção do intervalo de 0.4GHz para 0.6GHz. Esta exceção é causada porque o DVS do ARM não precisa mudar a tensão para simular 0.4GHz e 0.6GHz, e quando apenas a frequência muda, a redução de consumo de energia é diretamente compensada pelo aumento de tempo necessário para executar o programa.

Conclusão

Como conclusão do primeiro experimento, é possível confirmar que o DVS contínuo implica em diferentes tempos de execução de acordo com a frequência utilizada. E de acordo com o segundo experimento, é claro que a potência muda de acordo com a frequência, mas a modificação da frequência apenas resulta em economia de energia geral se a tensão elétrica mudar também.

Referências

  1. ARM - ARM1176JZF Development Chip Technical Reference
  2. RaspBerry Pi - RPiconfig
  3. clock_gettime - Man7Org
  4. Test program code - GitHub