- MacThrottle es una app basada en SwiftUI que muestra visualmente en la barra de menús cuando la Mac limita su rendimiento por sobrecalentamiento - código abierto
- Compara la API
ProcessInfo.thermalState de macOS y el comando powermetrics para explorar cómo detectar con precisión el estado térmico real del sistema
- Finalmente implementa una forma de leer el estado térmico usando las notificaciones que
thermald publica en el sistema notifyd de Darwin, sin requerir privilegios de root
- La app incluye gráficas de temperatura y velocidad del ventilador, íconos por color según el estado y notificaciones de macOS, además de soporte para iniciarse automáticamente al iniciar sesión
- Es una herramienta para entender en tiempo real el estado de gestión térmica de las Mac con Apple Silicon, útil como recurso de diagnóstico para desarrolladores y usuarios avanzados
Reconocer el problema del thermal throttling en la Mac
- En una M2 MacBook Air, al usar una pantalla externa 4K 120Hz, se producían caídas de rendimiento y retrasos de respuesta
- Como no tiene ventilador, no se puede detectar ruido, pero con el CPU al 100% el consumo de energía disminuía
- Con iStat Menus y MX Power Gadget se confirmó la caída de frecuencia y de consumo del CPU, diagnosticando thermal throttling
- El mismo fenómeno apareció también en una M4 Max MacBook Pro, mencionado como un problema derivado de las limitaciones del diseño térmico del modelo de 14 pulgadas
- Aunque la eficiencia energética de Apple Silicon sigue siendo alta, se buscó una forma de detectar directamente el estado térmico
Cómo comprobar programáticamente el estado térmico en macOS
- macOS expone el estado térmico de varias formas, pero carecen de consistencia
- El método recomendado por Apple es usar
ProcessInfo.thermalState de Foundation
- Ejemplos de salida:
nominal, fair, serious, critical
- El comando
powermetrics -s thermal, que requiere privilegios de root, también entrega esa información,
pero ambos métodos usan niveles de clasificación distintos
- Por ejemplo,
fair incluye tanto moderate como heavy de powermetrics
- En el momento en que ocurre el throttling real,
powermetrics lo muestra como heavy, pero ProcessInfo no permite distinguirlo
Uso de thermald y del sistema de notificaciones de Darwin
- Los datos de
powermetrics provienen del daemon thermald,
y thermald publica el estado actual de presión térmica como eventos del sistema notifyd
- Es posible consultar el estado con el comando
notifyutil -g com.apple.system.thermalpressurelevel
- Niveles de presión térmica definidos en el encabezado
OSThermalNotification.h:
nominal, moderate, heavy, trapping, sleeping
- Con código Swift que llama a
notify_register_check y notify_get_state,
se implementó una función para leer en tiempo real el estado térmico sin privilegios de root
Desarrollo de la app MacThrottle
- Se creó una app exclusiva para la barra de menús usando SwiftUI y MenuBarExtra
- El estado se muestra con el color de un ícono de termómetro (verde→rojo)
- Se desactiva el ícono del Dock configurando
LSUIElement de Info.plist en true
Enfoque inicial: helper de root con powermetrics
- Al inicio, para usar
powermetrics, que requiere privilegios de root,
se construyó un proceso auxiliar con LaunchDaemon y un script en bash
/usr/local/bin/mac-throttle-thermal-monitor escribía el estado cada 10 segundos en un archivo de /tmp
- La app leía periódicamente ese archivo para mostrarlo
Mejora: uso de notificaciones IPC de thermald
- Luego se cambió a un método que suscribe directamente los eventos de
notifyd
- Ya no requiere privilegios de root y simplifica el código
Visualización de temperatura y velocidad del ventilador
- Muestra en gráficas la temperatura del CPU/GPU y la velocidad del ventilador
- Al principio, usando API privadas de IOKit, la temperatura aparecía más baja de lo real (~80°C)
- Tomando como referencia el proyecto de código abierto Stats, se cambió a la interfaz SMC
- Hay que usar claves distintas según la generación del SoC (
Tp0D, Tf0E, etc.)
- Si SMC no funciona, hace fallback a IOKit
Implementación de la gráfica en la barra de menús
- La gráfica muestra tres tipos de información al mismo tiempo
- Color de fondo: estado térmico (verde~rojo)
- Línea continua: temperatura del CPU
- Línea punteada: proporción de velocidad del ventilador
- Recolecta datos cada 2 segundos y mantiene un historial de 10 minutos
- Ofrece tooltip con
onContinuousHover,
y al añadir .drawingGroup se logra renderizado por GPU para mostrarlo con fluidez incluso en pantallas de 120Hz
Notificaciones de macOS e inicio automático
- Se añadió una función para enviar notificaciones cuando cambia el estado térmico
- Puede notificar en transiciones a estados específicos o cuando se recupera
- También soporta configuración de inicio automático al iniciar sesión con la API
SMAppService
- Se controla con los métodos
register() / unregister() / status
Distribución y uso
- Como no hay cuenta de Apple Developer, no fue posible la notarización oficial
- Al instalar desde GitHub Releases, se requiere aprobación manual en
Privacy and Security
- En algunas Mac, solo puede ejecutarse si se compila directamente con Xcode
- El método de instalación y compilación está explicado en el README de GitHub
Conclusión
- MacThrottle es una herramienta ligera para vigilar en tiempo real el estado de thermal throttling en Mac con Apple Silicon
- Funciona sin privilegios de root y, mediante retroalimentación visual, notificaciones y gráficas,
ofrece a desarrolladores y usuarios de cargas intensivas visibilidad sobre el estado térmico del sistema
1 comentarios
Comentarios de Hacker News
Usé una MacBook Pro i9 de 2019, y la función para detectar thermal throttling podría ser así de simple
Es broma, pero sí fue bastante decepcionante comprar un CPU i9 caro y que rindiera peor que un i7
No sé por qué, pero así desapareció el throttling
Aun así, sigo usándola porque ya estoy acostumbrado al flujo de trabajo con macOS y Logic
Podría cambiarme a Linux, pero por ahora sigue siendo una máquina bastante usable
El throttling era terrible cada vez que usaba dos monitores externos y Adobe Creative Suite, pero con esos pads se solucionó
La desventaja es que la tapa inferior se calienta y cuesta usarla sobre las piernas, pero no me arrepiento en absoluto
Ahora me cambié a una MacBook Air M3 (24GB RAM) y estoy muy satisfecho
Si alguien todavía usa el modelo 2019, de verdad le recomiendo considerar la modificación con thermal pads en el VRM
Incluso en Dell todo mejoró mucho en cuanto cambiaron el i9 por un i7
Al final caímos en el marketing de “número más grande = mejor CPU”
Después me cambié a una M1 Max y fue otro mundo por completo
Ahora ya subí a una M3 Max, y Apple Silicon parece que va a durar bastante
Los ventiladores arrancaban apenas iniciaba, y al conectar dispositivos Thunderbolt también tenía kernel panics muy seguido
La MBP M1 Max que uso ahora es perfectamente estable
El proyecto se ve bastante bien
Pero como desarrollar en macOS es cada vez más difícil, me pregunto qué se puede hacer realmente aunque detectes el throttling
¿Ni siquiera se puede ajustar la velocidad de los ventiladores, y tampoco hacer undervolting, no?
La curva predeterminada era tan lenta que primero ocurría el throttling
En Apple Silicon, si usas High Power Mode, los ventiladores giran más rápido
Ahora ya no uso una curva personalizada, pero en la 14" M4 Max hace bastante ruido
La MacBook Air no tiene ventiladores, así que solo queda intentar disipar el calor
Con la configuración predeterminada pasaba de 90 grados, así que la dejé más conservadora
Enlace de GitHub
A veces algún proceso se descontrola y causa throttling, y para cuando me doy cuenta, la batería ya va por la mitad
Este problema pasa seguido cuando hay muchas apps corriendo en segundo plano
Si lo publican en Homebrew, pueden obtener firma de código y notarización gratis
Estaría muy bien que se distribuyera así
Mi hipótesis es que el problema no es el CPU, sino que el controlador USB satura térmicamente el sistema
Más que CPU/GPU, parece que el chasis se sobrecalienta, se bloquea la disipación y al final aparece el throttling
Habría que probar con otros adaptadores o monitores
Creo que tienes razón
Si la conecto a un monitor 4K 144Hz y abro Zoom o varios streams de video, se calienta muchísimo
Más que por el controlador USB, parece simplemente por la carga elevada
Parece que el sitio se cayó por un pico de tráfico
El repositorio es angristan/MacThrottle
Si en iStat Menus ves el CPU al 100% pero con bajo consumo de energía, podrías pensar que es throttling,
pero lo mismo también pasa cuando está conectado a un cargador USB-C de baja potencia
Estaría bien agregar una función para detectar la potencia del cargador
Como se calentaba más mientras cargaba, el throttling empeoraba, pero se solucionó cargándola antes de la sesión
Ahí entendí por qué en generaciones posteriores salieron adaptadores de mayor potencia
¿No es esa la variable de control directa?
Si dejas el uso del CPU y el consumo del sistema visibles en la barra de menús, puedes detectar enseguida cualquier anomalía
exelban/stats
Me di cuenta al ver que el uso del CPU seguía alto pero el consumo bajaba
Ojalá la próxima MacBook Air M5 venga con refrigeración por vapor chamber
Ahora mismo parece que Apple prioriza minimizar el ruido por encima de disipar el calor
Por eso fuerzo una velocidad mínima más alta en los ventiladores
Cuando el cuerpo llega al equilibrio térmico con el entorno, la capacidad de disipación toca su límite
Si hay ventilador, con una placa de cobre y flujo de aire suele ser suficiente
Al final es un problema de conservación de la energía
Parece haber un bug en la notificación de thermal pressure
Me pregunto si en la app también te encontraste con ese problema
Issue relacionado
ProcessInfo.processInfo.thermalStatePero con el método actual de notificación de thermald no tengo ese problema
Me pregunto por qué declaraste directamente la API de Darwin con
@_silgen_name¿No se puede acceder con
import Darwin?import Darwin