Raspberry Pi 4: Teste de Estresse de CPU, GPU e RAM

Do problema térmico à compreensão do hardware, à criação das cargas e à validação do ensaio.
Meu Raspberry Pi 4 principal funciona como servidor doméstico e concentra serviços que utilizo diariamente. Com o crescimento dessa estrutura, comecei a observar uma questão que até então parecia secundária: o aquecimento do equipamento, principalmente quando o ambiente já estava quente.
Durante bastante tempo utilizei um case de alumínio com dissipação passiva. A solução era compacta, silenciosa e exigia pouca manutenção, algo importante para um servidor que permanece ligado continuamente. Entretanto, em algumas situações o case ficava desconfortavelmente quente ao toque, e medições pontuais anteriores chegaram perto dos 70 °C.
Isso me trouxe uma dúvida: o sistema de dissipação realmente conseguiria lidar com uma situação prolongada de processamento intenso, ou o Raspberry Pi começaria a limitar seu próprio desempenho? Eu precisava responder a essa pergunta sem esperar que uma tarefa real fosse prejudicada.
1. O problema: como avaliar o limite térmico em uso real?
O servidor central usa um Raspberry Pi 4 de 8 GB, reaproveitado de um gateway LoRaWAN da Helium. Nele continuam funcionando Nextcloud, Home Assistant, sincronização de arquivos e outras aplicações. No laboratório, tenho outro Raspberry Pi 4, de 2 GB, que costuma executar cargas mais pontuais. Ambos já usaram dissipação passiva, mas o servidor principal passou a me preocupar porque a demanda de processamento estava aumentando.
Eu não tinha uma evidência de thermal throttling, quando o processador diminui o desempenho para se proteger do calor. Também não seria correto concluir que o equipamento estava em risco de dano só porque o case estava quente. O que eu precisava era descobrir se o conjunto de refrigeração suportaria uma carga intensa e sustentada e identificar qualquer limitação que aparecesse durante o processo.
O uso cotidiano não fornecia uma comparação confiável: a geração de miniaturas, os acessos ao armazenamento, os serviços de rede e as automações não aconteciam sempre com a mesma intensidade. Além disso, não faria sentido criar várias aplicações de produção apenas para ocupar o processador. Antes de escolher uma forma de gerar carga, eu precisava entender por que essa carga seria necessária e quais partes do Raspberry Pi deveriam ser exigidas.
2. Por que gerar uma carga de processamento?
O Raspberry Pi não produz calor apenas porque está ligado. Uma parte importante da energia elétrica consumida pelo SoC acaba sendo transformada em calor, e esse comportamento muda conforme o hardware executa operações, alterna estados internos e utiliza seus diferentes blocos. Quando mais núcleos trabalham intensamente, a demanda elétrica e a geração de calor normalmente aumentam.
Por isso, olhar a temperatura em repouso não é suficiente para avaliar um dissipador. Com pouca atividade, o sistema operacional pode reduzir a frequência da CPU e a quantidade de operações realizadas. O equipamento parece frio, mas isso não demonstra como vai se comportar durante vários minutos de cálculo pesado.
Eu precisava provocar esse aquecimento de maneira controlada e repetível: primeiro observar a temperatura inicial, depois manter uma atividade intensa por tempo suficiente para acompanhar sua evolução e, ao final, verificar o resfriamento. O importante não seria apenas descobrir a maior temperatura, mas entender como ela cresceria, se estabilizaria e diminuiria.
Também era necessário distinguir dois problemas diferentes. O thermal throttling está associado ao controle de temperatura. Já a subtensão acontece quando a alimentação elétrica cai abaixo do nível adequado e também pode levar à redução de desempenho. Se um ensaio registrar throttling por falta de tensão, não posso atribuir automaticamente o resultado à eficiência do dissipador.
Definido o motivo para gerar carga, faltava a próxima pergunta: qual parte do Raspberry Pi eu precisava ocupar para produzir um ensaio representativo? É aqui que a arquitetura do equipamento passa a ser fundamental.
3. O que existe dentro do Raspberry Pi 4?
Para responder a essa pergunta, comecei pelo hardware. O Raspberry Pi 4 utiliza o Broadcom BCM2711, um system-on-chip (SoC) que reúne CPU, GPU, controladores e outras funções em um circuito integrado. Segundo a documentação oficial da Raspberry Pi, a CPU é formada por quatro núcleos ARM Cortex-A72 de 64 bits, enquanto a parte gráfica utiliza a GPU VideoCore VI, com unidade de renderização V3D.
Os núcleos ARM são os executores das tarefas gerais do Linux. A GPU é um subsistema diferente, especializado em processamento gráfico. Por isso, não faz sentido dizer que ela tem “quatro núcleos” só porque a CPU tem quatro. A ilustração mostra a GPU como um bloco gráfico distinto. É um esquema funcional do silício, não uma fotografia ou um mapa real da disposição dos transistores.
Também existe um ponto importante: a RAM não está dentro do BCM2711. A capacidade de memória depende do modelo da placa, enquanto a arquitetura principal de CPU e GPU permanece a mesma. Essa distinção também aparece nas especificações oficiais do Raspberry Pi 4.
O Raspberry Pi 4 Model B não existe apenas nas configurações que tenho aqui. De acordo com a ficha oficial atualizada em abril de 2026, a família contempla versões com 1 GB, 2 GB, 3 GB, 4 GB e 8 GB de RAM LPDDR4. A ilustração mostra todas essas capacidades, destacando os modelos de 2 GB e 8 GB, que foram os únicos utilizados no meu experimento. A quantidade de RAM altera a capacidade de executar aplicações e manter dados em memória, mas não determina sozinha o clock de CPU.


Na prática, o Raspberry Pi do laboratório foi testado a 1,5 GHz e o servidor também pôde operar a 1,8 GHz. Essa diferença não se explica simplesmente pela quantidade de RAM; ela envolve a revisão da placa, o circuito de alimentação e o firmware. Vou explicar essa particularidade quando chegarmos à comparação dos perfis de frequência.
4. Quatro núcleos significam quatro tarefas?
Não exatamente. Um núcleo é uma unidade física de execução da CPU. Um processo é um programa em execução, e um processo pode ter uma ou mais threads, que são fluxos de instruções organizados pelo sistema operacional. O Linux pode manter dezenas ou centenas de processos e threads disponíveis, mesmo que o Raspberry Pi 4 tenha apenas quatro núcleos físicos.
O que o sistema faz é escalonar o trabalho: em cada instante, escolhe quais tarefas vão utilizar os núcleos. Quando há mais tarefas prontas do que núcleos disponíveis, elas se alternam em pequenas fatias de tempo. Em outras palavras, quatro núcleos não significam um limite de quatro programas abertos; significam que até quatro fluxos de instruções podem executar simultaneamente nesses núcleos, considerando a arquitetura utilizada, enquanto outros aguardam sua vez.
Essa distinção muda completamente o raciocínio do estresse. Um programa que utiliza intensamente apenas uma thread não ocupa automaticamente os quatro núcleos. No monitor agregado de CPU, um núcleo totalmente ocupado representa aproximadamente 25% da capacidade total de quatro núcleos, embora serviços de fundo e o escalonador possam alterar o valor observado. Já quatro trabalhadores de cálculo independentes podem ocupar praticamente toda a CPU.
Há ainda a GPU. Ela não é simplesmente um quinto núcleo ARM: trata-se de um subsistema diferente, especializado em operações gráficas. Um processo pode acionar a GPU, mas isso não significa que o trabalho pesado esteja sendo executado pelos núcleos da CPU. Por isso, uma carga somente de CPU não reproduz todas as condições possíveis de aquecimento do SoC.
A memória RAM completa o cenário. Ter 8 GB em vez de 2 GB permite manter mais dados e processos em memória, mas não transforma automaticamente a CPU em uma versão com mais núcleos. Para o meu teste, faria mais sentido controlar a atividade de memória sem tentar consumi-la por completo, já que os dois Raspberry continuariam desempenhando suas funções habituais.
5. Da arquitetura à criação de uma ferramenta de estresse
Depois de entender o que precisava ser exigido, o próximo passo foi organizar as condições do ensaio. Eu não queria apenas “colocar a CPU em 100%”: precisava comparar carga em um único núcleo, nos quatro núcleos, na GPU e em cenários combinados. Também seria necessário registrar temperatura, frequência e sinais de proteção durante a execução, para não confundir aquecimento normal com throttling ou falha elétrica.
Foi a partir desses requisitos que desenvolvi, com auxílio de IA, o FullChip Benchmark. Ele foi criado especificamente para o meu experimento com o Raspberry Pi 4. Não pretende substituir ferramentas de benchmark já consolidadas nem medir o desempenho absoluto de cada bloco do chip. Sua função era gerar condições de carga repetíveis e produzir dados para avaliar o comportamento térmico das montagens.
Para não depender de uma única carga artificial, organizei o teste em cinco estágios. Cada estágio responde a uma pergunta específica, e a combinação deles permite observar como o conjunto térmico reage à medida que diferentes partes da plataforma entram em atividade.
6. Como distribuí as cargas entre CPU, GPU e RAM?
Eu dividi o FullChip em cinco estágios. Em vez de executar uma única carga misturada, a ideia foi isolar primeiro CPU e GPU, depois combinar os recursos. Assim, o gráfico final ajuda a responder se uma montagem se comporta bem sob carga leve, mas piora quando mais blocos entram em atividade.

6.1. Um trabalhador de CPU: cpu_single
O primeiro estágio usa um trabalhador do stress-ng para executar o método matrixprod, isto é, operações repetidas de multiplicação de matrizes. A CPU do Raspberry Pi 4 possui quatro núcleos, mas apenas um trabalhador de carga pesada é criado. Isso não fixa o processo fisicamente ao núcleo 0; o escalonador do Linux pode movê-lo entre os núcleos. O que estamos controlando é a quantidade de trabalhadores.
6.2. Quatro trabalhadores: cpu_multi
No teste multicore, o programa cria quatro trabalhadores com o mesmo método de cálculo. Com quatro núcleos disponíveis, o sistema pode ocupar praticamente toda a capacidade de CPU, desde que não exista outra limitação. Esse estágio mostrou uma diferença térmica muito mais expressiva entre os dissipadores.
6.3. GPU isolada: gpu_3d
Nesta etapa, o foco passa a ser o motor gráfico V3D. O utilitário realiza renderização acelerada por hardware sem exigir monitor conectado. A CPU ainda participa do envio de comandos, mas não é submetida ao mesmo estresse de quatro trabalhadores dos ensaios de CPU.
6.4. CPU e GPU simultâneas: cpu_gpu
O quarto cenário combina os quatro trabalhadores da CPU com a renderização gráfica contínua. Ele é especialmente útil para observar a resposta térmica quando mais de um bloco relevante do SoC trabalha sob carga ao mesmo tempo.
6.5. CPU, GPU e RAM: cpu_gpu_ram
Por fim, a suíte adiciona um trabalhador de memória ao conjunto anterior. O parâmetro --vm-keep mantém o bloco alocado, aumentando a atividade de memória sem tentar consumir toda a RAM. O tamanho é escolhido pelo programa com base na memória disponível, limitado a uma fração conservadora e a 512 MiB. O propósito não é provocar falta de memória, mas acrescentar uma carga controlada e preservar os serviços já em funcionamento.
7. Quais comandos geram as cargas?
O coordenador do projeto é o rpi4_fullchip.py. Ele inicia processos de carga, controla os tempos, lê os sensores e gera CSVs e resumos em JSON. Os scripts de shell são pontos de entrada para instalar, diagnosticar e executar os perfis de cada equipamento.
| Comando ou arquivo | Função prática |
|---|---|
instalar_dependencias.sh | Prepara stress-ng, bibliotecas EGL/GLES/GBM e o programa gráfico. |
diagnostico_rapido.sh | Lê modelo, kernel, relógios, estado de throttling e faz uma validação breve do V3D. |
diagnostico_frequencia_1500.sh | Confere se o limite temporário de 1,5 GHz pode ser aplicado e restaurado. |
testar_2gb_case.sh | Executa os cinco cenários no laboratório, a 1,5 GHz. |
testar_8gb_torre.sh | Executa os cinco cenários a 1,5 GHz e depois a 1,8 GHz no servidor. |
comparar.py | Consolida os resultados em gráficos e tabelas comparativas. |
Na prática, os comandos de carga internos seguem a mesma ideia dos exemplos abaixo. O usuário normalmente não precisa digitá-los manualmente, porque o coordenador já os executa na fase correspondente:
# Um trabalhador CPU, método matrixprodstress-ng --cpu 1 --cpu-method matrixprod --metrics-brief# Quatro trabalhadores CPU, mesmo métodostress-ng --cpu 4 --cpu-method matrixprod --metrics-brief# Acrescenta um trabalhador de memória ao estresse CPU# (o tamanho real é calculado e limitado pelo programa)stress-ng --cpu 4 --cpu-method matrixprod --vm 1 --vm-bytes 256M --vm-keep
No terceiro exemplo, 256M é ilustrativo: a suíte calcula o tamanho de acordo com a disponibilidade de RAM. O stress-ng é uma ferramenta de geração de cargas sintéticas para Linux, documentada no manual oficial do comando.
Depois de instalar as dependências e confirmar que a parte gráfica está operacional, a bateria é iniciada de forma simples:
# Raspberry Pi 4 de 2 GB, case passivobash testar_2gb_case.sh# Raspberry Pi 4 de 8 GB, torre ventiladabash testar_8gb_torre.sh
O argumento --stages permite escolher cenários, como --stages cpu_gpu. O argumento --smoke executa uma versão curta para validar a cadeia antes de uma carga prolongada. Também é possível selecionar uma frequência específica no perfil do servidor, como --freqs 1500.
8. Como testar a GPU sem monitor?
Essa foi uma das dificuldades mais interessantes do projeto. Como os meus Raspberry Pi operam como servidores, parte dos testes é feita remotamente, sem sessão gráfica local. As primeiras tentativas com glmark2-es2-drm encontraram problemas para localizar um conector DRM adequado. Isso não prova que a GPU está com defeito; apenas mostra que aquele caminho de renderização dependia de condições indisponíveis na instalação.
A solução foi utilizar um programa de renderização headless, apoiado em EGL e GBM, capaz de acessar os dispositivos de renderização disponíveis e desenhar em um framebuffer off-screen. Ele verifica o GL_RENDERER e exige que o resultado identifique a GPU V3D real, com frames gerados.

Isso evita um erro importante: usar um software renderer, como llvmpipe, e acreditar que a GPU física está sendo estressada. A suíte rejeita esse tipo de execução. Também é preciso lembrar que confirmar frames em V3D não equivale a medir utilização percentual de GPU. O programa valida renderização acelerada, mas não oferece um medidor de ocupação absoluta do bloco gráfico.
9. Por que medir repouso, estresse e resfriamento?
Para cada cenário, o programa percorre um ciclo de 510 segundos: 30 segundos de repouso, 300 segundos de estresse e 180 segundos de resfriamento. Esse formato foi escolhido porque uma temperatura máxima isolada não descreve toda a resposta térmica. Um dissipador pode aquecer rapidamente no início e depois estabilizar; outro pode subir mais devagar, mas continuar esquentando até o fim.

O ciclo completo permite comparar a temperatura inicial, a evolução sob carga e a capacidade de recuperação. Os cinco estágios representam 42 minutos e 30 segundos de medição programada por frequência. No meu comparativo, foram cinco estágios no Raspberry de 2 GB e dez no de 8 GB, totalizando 15 ensaios completos, além do tempo necessário às verificações e à organização dos resultados.
10. Como acompanhei temperatura e throttling?
Durante a execução, a suíte coletava a cada segundo temperatura do SoC, uso agregado de CPU, frequência ARM, clock V3D, memória disponível, estado de processos e indicadores de subtensão e throttling. O objetivo não era apenas aquecer, mas saber se a carga ainda estava acontecendo nas condições esperadas.

Por exemplo, a leitura get_throttled=0x50000 registra que já houve subtensão e throttling desde o boot, mas não significa que ambos estejam ativos naquele instante. Na tentativa inicial no laboratório, houve um episódio de subtensão ativa e o programa interrompeu a carga. Isso é diferente de throttling térmico e precisa ser identificado para não contaminar a interpretação do dissipador.
O script também possui critérios preventivos de parada: temperatura em torno de 78 °C, subtensão ativa, throttling ativo, mudança inesperada do limite de frequência, memória disponível abaixo de um mínimo e falha de sensores ou processos. É uma proteção operacional, não uma garantia contra qualquer falha elétrica ou de armazenamento. Em um servidor com serviços importantes, esse tipo de teste deve ser feito com backup e durante uma janela em que a carga intensa seja aceitável.
11. Por que as frequências eram diferentes?
O Raspberry Pi do laboratório, de 2 GB e Rev 1.1, foi testado a 1,5 GHz. O servidor, de 8 GB e Rev 1.4, que usava a torre ventilada, foi testado duas vezes: a 1,5 e a 1,8 GHz. A primeira frequência permite uma comparação mais próxima entre os equipamentos. A segunda mostra a resposta térmica do servidor na frequência maior.
Entretanto, não se deve interpretar as placas como se fossem absolutamente idênticas: elas têm revisões diferentes, capacidade de RAM diferente, serviços distintos e soluções térmicas próprias. Os testes foram feitos durante o uso normal dos equipamentos, sem parar os serviços habituais de Nextcloud, Home Assistant ou laboratório. A visão computacional temporária que eu havia usado para acompanhar meu gato em uma viagem já estava desligada.
Portanto, os ensaios são uma comparação prática de duas montagens reais. Eles ajudam muito a avaliar a escolha térmica no meu ambiente, mas não isolam matematicamente todos os fatores de um experimento de bancada controlado.
11.1. Por que o meu Raspberry de 2 GB não trabalha a 1,8 GHz por padrão?
Durante a preparação do benchmark, apareceu uma diferença que não era evidente à primeira vista: meu Raspberry Pi 4 de 2 GB é uma Rev 1.1 e o de 8 GB é uma Rev 1.4. Ambos utilizam o BCM2711 e quatro núcleos Cortex-A72, mas a versão de laboratório estava configurada e suportada pelo driver com limite de 1,5 GHz, enquanto o servidor permitia 1,8 GHz.
A explicação não está na capacidade de RAM nem simplesmente em existir um chip mais rápido. Em um comunicado técnico de 2021, a Raspberry Pi explicou que revisões mais recentes incorporaram uma fonte chaveada dedicada à alimentação do núcleo do SoC, qualificada para sustentar o ponto de operação de 1,8 GHz. Com o suporte do firmware, a opção arm_boost permite elevar de 1,5 para 1,8 GHz a frequência turbo padrão nas placas compatíveis. A Rev 1.1 não dispõe do mesmo projeto de alimentação, portanto não recebe automaticamente esse modo de operação.
Isso não significa que uma Rev 1.1 seja fisicamente incapaz de alcançar 1,8 GHz. É possível tentar frequências mais altas por overclock, mas isso altera a condição nominal e pode exigir ajustes elétricos e validação de estabilidade. Não fiz overclock: o benchmark respeitou o limite informado pelo sistema para cada placa. No servidor de 8 GB, utilizei 1,5 GHz para aproximar a comparação entre as duas montagens e depois 1,8 GHz para observar o comportamento do equipamento em seu perfil de maior frequência.
Assim, a diferença de clock demonstrada aqui é uma consequência de revisão de hardware, circuito de alimentação e configuração de firmware, e não uma regra segundo a qual todo Raspberry Pi 4 de 2 GB funciona a 1,5 GHz e todo modelo de 8 GB funciona a 1,8 GHz.
12. Validação: o sistema conseguiu gerar o ensaio?
Depois dos ajustes de diagnóstico, principalmente na validação da GPU V3D sem monitor e no controle de frequência, consegui executar a bateria final nos dois equipamentos. Foram cinco cenários no Raspberry Pi de 2 GB a 1,5 GHz e dez no de 8 GB, distribuídos entre 1,5 e 1,8 GHz. Todos os 15 cenários dessa bateria terminaram com status OK.
Isso era exatamente o que eu precisava validar: a suíte conseguiu manter cargas de CPU, GPU e memória durante os períodos programados, registrar temperatura e frequência e acompanhar os sinais de limitação. Na bateria final, não houve amostras com subtensão ou throttling ativos. Uma ocorrência elétrica havia interrompido uma tentativa anterior no laboratório, demonstrando também a utilidade da parada preventiva. Como o monitor faz leituras discretas e os indicadores históricos já podiam estar registrados, os arquivos não garantem que absolutamente nenhum evento breve tenha ocorrido entre amostras.
O gráfico abaixo é uma amostra dos resultados gerados pela ferramenta, no cenário combinado de CPU + GPU + RAM. Ele mostra o ciclo completo, começando pelo repouso, passando por cinco minutos de carga e terminando no resfriamento. No equipamento com case passivo, a temperatura máxima observada nesse cenário foi de 63,30 °C; na torre ventilada, foram 40,89 °C a 1,5 GHz e 43,82 °C a 1,8 GHz.

O objetivo desta página não é repetir toda a análise de dissipação. O artigo com os resultados completos, os cinco cenários e os gráficos comparativos mostra em detalhe a diferença entre o case passivo e a torre ventilada. Aqui, esse gráfico serve como evidência de que o sistema de estresse produziu uma medição utilizável, e não apenas uma sequência de comandos.
A leitura tem limites importantes: o FullChip não mede watts térmicos diretamente, não comprova 100% de utilização de todos os blocos internos do BCM2711 e não mede o percentual de ocupação da GPU. Além disso, os Raspberry Pi tinham revisões, capacidades de RAM e cargas de fundo diferentes. A finalidade foi comparar duas montagens reais de maneira estruturada, não criar um teste padronizado universal.
13. Conclusão: da necessidade à validação
O ponto de partida foi uma dúvida sobre refrigeração, mas eu não conseguiria respondê-la apenas encostando no case ou acompanhando a temperatura em repouso. Primeiro foi necessário compreender o hardware: quantos núcleos poderiam executar trabalho simultâneo, como o Linux distribui os processos, por que a GPU tem um funcionamento próprio e como as cargas diferentes afetam o aquecimento.
A partir dessa compreensão, pude estruturar um procedimento que realmente atendesse ao problema: gerar cargas previsíveis em um núcleo, nos quatro núcleos, na GPU e na memória, acompanhar cada fase do ensaio e interromper a execução diante de sinais de risco ou invalidação. A ferramenta também funcionou sem exigir que eu interrompesse os serviços normais dos dois Raspberry Pi durante as medições.
O sistema resolveu a necessidade para a qual foi criado. Os 15 cenários da bateria final foram concluídos e forneceram curvas de temperatura, dados de frequência e registros de proteção que permitiram avaliar as montagens. Isso não transforma o FullChip em um benchmark universal nem comprova ausência absoluta de eventos breves entre amostras. Mostra, porém, que pude reproduzir um período de carga intensiva e observar seus efeitos sem depender de uma falha aparecer no uso cotidiano. Os gráficos e a comparação entre dissipação ativa e passiva estão detalhados no artigo de resultados do blog. Os arquivos do FullChip Benchmark estão preparados para disponibilização no GitHub, junto das instruções de execução.
Você precisa fazer login para comentar.