5 pontos por GN⁺ 2025-12-29 | 1 comentários | Compartilhar no WhatsApp
  • MacThrottle é um app baseado em SwiftUI que avisa visualmente na barra de menus quando o Mac está limitando o desempenho por superaquecimento - código aberto
  • Compara a API ProcessInfo.thermalState do macOS com o comando powermetrics, explorando formas de detectar com precisão o estado térmico real do sistema
  • No fim, implementa uma forma de ler o estado térmico sem privilégios de root usando notificações publicadas pelo thermald no sistema notifyd do Darwin
  • O app inclui gráficos de temperatura e velocidade da ventoinha, ícones coloridos por estado e notificações do macOS, além de suporte para iniciar automaticamente no login
  • É uma ferramenta para acompanhar em tempo real o estado de gerenciamento térmico de Macs com Apple Silicon, oferecendo um recurso de diagnóstico útil para desenvolvedores e usuários avançados

Entendendo o problema de thermal throttling no Mac

  • Ao usar um monitor externo 4K 120Hz com um M2 MacBook Air, surgiram quedas de desempenho e atrasos na resposta
    • Como ele não tem ventoinha, não havia ruído para perceber, mas o consumo de energia caía enquanto a CPU seguia em 100% de uso
  • Com iStat Menus e MX Power Gadget, foi possível confirmar queda de frequência e de consumo da CPU, diagnosticando thermal throttling
  • O mesmo fenômeno também apareceu em um M4 Max MacBook Pro, citado como consequência dos limites do projeto térmico do modelo de 14 polegadas
  • A eficiência energética do Apple Silicon continua alta, mas a ideia era encontrar uma forma de detectar diretamente o estado térmico

Como verificar programaticamente o estado térmico no macOS

  • O macOS expõe o estado térmico de várias formas, mas com pouca consistência
  • O método recomendado pela Apple é usar ProcessInfo.thermalState de Foundation
    • Exemplos de saída: nominal, fair, serious, critical
  • O comando powermetrics -s thermal, que exige privilégios de root, também fornece essa informação,
    mas os dois métodos usam granularidades diferentes para os estados
    • Ex.: fair inclui tanto moderate quanto heavy do powermetrics
  • Na prática, o momento em que o throttling acontece aparece como heavy no powermetrics, mas não pode ser distinguido via ProcessInfo

Uso de thermald e do sistema de notificações Darwin

  • Os dados do powermetrics vêm do daemon thermald,
    e o thermald publica o estado atual de pressão térmica como evento do sistema notifyd
  • É possível verificar o estado com o comando notifyutil -g com.apple.system.thermalpressurelevel
  • Níveis de pressão térmica definidos no header OSThermalNotification.h:
    • nominal, moderate, heavy, trapping, sleeping
  • Em Swift, foi implementada a leitura do estado térmico em tempo real sem privilégios de root chamando notify_register_check e notify_get_state

Desenvolvimento do app MacThrottle

  • O app foi criado como um aplicativo só de barra de menus usando SwiftUI e MenuBarExtra
    • O estado é indicado pela cor de um ícone de termômetro (verde → vermelho)
    • Em Info.plist, LSUIElement foi definido como true para desativar o ícone no Dock

Abordagem inicial: helper root com powermetrics

  • No começo, para usar powermetrics, que exige root,
    foi montado um processo auxiliar com LaunchDaemon e script bash
    • /usr/local/bin/mac-throttle-thermal-monitor gravava o estado em um arquivo em /tmp a cada 10 segundos
    • O app lia esse arquivo periodicamente para exibir as informações

Melhoria: uso das notificações IPC do thermald

  • Depois, a solução foi trocada por uma assinatura direta dos eventos do notifyd
    • Sem necessidade de privilégios de root e com código mais simples

Exibição de temperatura e velocidade da ventoinha

  • O app mostra gráficos de temperatura de CPU/GPU e velocidade da ventoinha
  • No início, ao usar API privada do IOKit, a temperatura aparecia abaixo do real (~80°C)
  • Depois, com referência ao projeto open source Stats, a leitura passou para a interface SMC
    • Dependendo da geração do SoC, é preciso usar chaves diferentes (Tp0D, Tf0E etc.)
  • Se o SMC não funcionar, há fallback para IOKit

Implementação do gráfico na barra de menus

  • O gráfico exibe três tipos de informação ao mesmo tempo
    • Cor de fundo: estado térmico (verde ~ vermelho)
    • Linha contínua: temperatura da CPU
    • Linha pontilhada: proporção da velocidade da ventoinha
  • Os dados são coletados a cada 2 segundos, mantendo histórico de 10 minutos
  • Há tooltip com onContinuousHover,
    e foi adicionado .drawingGroup para renderização por GPU, mantendo fluidez mesmo em telas de 120Hz

Notificações do macOS e inicialização automática

  • Foi adicionada a função de enviar notificações quando o estado térmico muda
    • É possível notificar em transições específicas de estado ou na recuperação
  • Também há suporte para iniciar automaticamente no login com a API SMAppService
    • Controle via métodos register() / unregister() / status

Distribuição e uso

  • Como não há conta Apple Developer, não foi possível fazer a notarização oficial
    • Ao instalar pela release no GitHub, é necessário aprovar manualmente em Privacy and Security
    • Em alguns Macs, só é possível executar compilando diretamente pelo Xcode
  • As instruções de instalação e build estão descritas no README do GitHub

Conclusão

  • O MacThrottle é uma ferramenta leve para monitorar em tempo real o estado de thermal throttling em Macs com Apple Silicon
  • Funciona sem privilégios de root e oferece feedback visual, notificações e gráficos,
    ajudando desenvolvedores e usuários de cargas intensas a entender o estado térmico do sistema

1 comentários

 
GN⁺ 2025-12-29
Comentários do Hacker News
  • Usei um MacBook Pro i9 de 2019, e acho que a função para detectar thermal throttling poderia ser tão simples assim

    function isThermalThrottling() {
      return true;
    }
    

    É brincadeira, mas foi bem decepcionante comprar um CPU i9 caro e ver ele performar pior que um i7

    • Também uso o mesmo modelo, e só consegui resolver o problema carregando pela porta da direita
      Não sei por quê, mas assim o throttling desapareceu
      Mesmo assim, continuo usando porque já estou acostumado com o workflow baseado em macOS e Logic
      Até poderia migrar para Linux, mas hoje ainda é uma máquina bem utilizável
    • Também usei o modelo i9 de 2019, e colocar thermal pads no módulo VRM transformou ele completamente, como se fosse outro computador
      O throttling era pesado sempre que eu usava dois monitores externos e o Adobe Creative Suite, mas esses pads resolveram
      A desvantagem é que a parte de baixo fica quente demais para usar no colo, mas não me arrependo nem um pouco
      Agora troquei por um M3 MacBook Air (24GB RAM) e estou muito satisfeito
      Se você ainda usa o modelo de 2019, recomendo muito considerar a modificação com thermal pads no VRM
    • Na real, acho que o próprio i9 era um CPU inadequado para notebook
      Até na Dell melhorou muito assim que trocaram o i9 por um i7
      Foi basicamente cair no marketing de “número maior = CPU melhor”
    • Também passei pelo mesmo problema, especialmente quando conectava dois monitores externos
      Depois troquei por um M1 Max e parecia outro mundo
      Agora fiz upgrade para um M3 Max, e o Apple Silicon parece que vai durar bastante tempo
    • Aquele notebook foi o pior computador que já usei
      As ventoinhas ligavam assim que iniciava, e também dava kernel panic com frequência ao conectar dispositivos Thunderbolt
      O M1 Max MBP que uso agora é perfeitamente estável
  • O projeto parece bem legal
    Só que desenvolver no macOS está ficando cada vez mais difícil, e mesmo detectando throttling fico na dúvida sobre o que dá para fazer de fato
    Não dá para controlar a velocidade das ventoinhas, e undervolting também não é impossível?

    • No meu caso, eu ajustava manualmente a curva das ventoinhas com o iStat Menus
      A curva padrão era lenta demais, então o throttling acontecia antes
      No Apple Silicon, usar o High Power Mode faz as ventoinhas girarem mais rápido
      Hoje não uso mais curva personalizada, mas no 14" M4 Max ele faz bastante barulho
      O MacBook Air não tem ventoinha, então só resta tentar dissipar o calor
    • Eu uso Macs Fan Control para ajustar o RPM das ventoinhas conforme a temperatura da CPU
      Com a configuração padrão, passava de 90 graus, então deixei tudo mais conservador
      Link do GitHub
    • Eu precisava muito de um app assim, e agora ele existe
      Às vezes algum processo dispara e causa throttling, e até eu perceber a bateria já foi embora pela metade
    • No fim, tudo o que dá para fazer é fechar o app ou dar uma pausa por um tempo
      Esse problema acontece bastante quando há muitos aplicativos rodando em segundo plano
  • Se entrar no Homebrew, dá para ter assinatura de código e notarização de graça
    Seria ótimo se fosse distribuído assim

    • Boa informação. Agora fiquei curioso se também existe algum jeito gratuito de assinar para Windows
    • Ah, eu não sabia. Achei que dependia das configurações do desenvolvedor, vou pesquisar
  • Minha hipótese é que o problema não é o CPU, e sim o controlador USB saturando termicamente
    Parece uma estrutura em que não é CPU/GPU que superaquece, mas o chassi, bloqueando a dissipação e acabando em throttling
    Vale a pena testar com outros adaptadores ou monitores

    • Também uso um i9 de 2019, e quando troquei a porta de carregamento o throttling sumiu
      Acho que você está certo
    • Não entendo completamente, mas o meu M2 Air também apresenta algo parecido
      Quando conecto a um monitor 4K 144Hz e abro Zoom ou vários streams de vídeo, ele esquenta bastante
      Parece mais simplesmente carga alta do que algo causado pelo controlador USB
    • Esse fenômeno é chamado de thermal soaking
  • Parece que o site caiu por causa de pico de tráfego
    O repositório é angristan/MacThrottle

    • Corrigido. O Cloudflare Workers estava configurado em modo fail closed, então estava bloqueando o tráfego
  • No iStat Menus, se a CPU está a 100% mas o consumo de energia está baixo, dá para pensar que é throttling,
    mas a mesma coisa também acontece quando está conectado a um carregador USB-C de baixa potência
    Seria legal adicionar uma função para detectar a potência do carregador

    • Também tive esse problema jogando uma sessão de D&D num M1 MacBook Air
      Como ele esquentava mais enquanto carregava, o throttling piorava, mas resolveu quando passei a carregar antes da sessão
    • No passado já aconteceu de a saída do adaptador de energia ser insuficiente, e durante um jogo a bateria descarregar até o computador desligar
      Depois disso eu entendi por que as gerações seguintes vieram com adaptadores de energia maiores
    • Nesse caso, fico me perguntando por que não dá para determinar throttling só pela temperatura dos núcleos
      A temperatura não é justamente a variável de controle?
    • O iStat Menus mostra a potência do carregador, mas ainda continuo sem entender por que esse fenômeno acontece
  • Se você deixar o uso de CPU e a potência do sistema visíveis na barra de menus, dá para perceber anomalias na hora
    exelban/stats

    • Foi assim que comecei a suspeitar de throttling pela primeira vez
      Notei porque o uso de CPU estava alto, mas o consumo de energia caía
  • Espero que o próximo MacBook Air M5 venha com refrigeração por vapor chamber
    Hoje parece que a Apple prioriza minimizar ruído em vez de dissipação térmica
    Por isso eu forço uma velocidade mínima mais alta para as ventoinhas

    • Vapor chamber é bom para dispersão térmica instantânea, mas no fim o calor acaba sendo transferido para o corpo de alumínio
      Quando o corpo atinge equilíbrio térmico com o ambiente, a dissipação bate no limite
      Se houver ventoinha, uma placa de cobre com fluxo de ar já resolve bem
      No fim, é uma questão de conservação de energia
  • Parece haver um bug no alerta de thermal pressure
    Queria saber se o app também sofreu com isso
    Issue relacionada

    • Também vi o estado não ser atualizado ao usar ProcessInfo.processInfo.thermalState
      Mas com o método atual de notificação do thermald esse problema não acontece
  • Fiquei curioso por que foi usado @_silgen_name para declarar diretamente a API do Darwin
    Não dá para acessar com import Darwin?

    • Pelo visto, só com import Darwin essa API realmente não fica exposta