Intel y AMD: quién fija el límite de potencia del CPU

Hace unas semanas conté cómo limité térmicamente una notebook Intel usada como CPU box en clamshell —tapa cerrada, monitor portátil encima, la máquina debajo de todo—: Gestión térmica en notebook clamshell con RAPL y tuned. La idea era bajar a mano el techo de potencia para que el CPU no entrara en throttling (que no se frenara solo al recalentarse).

Cuando fui a repetir lo mismo en un equipo AMD Ryzen, el ejercicio derivó en algo más interesante que portar una receta. Intel y AMD no se diferencian solo en cómo se toca el límite: se diferencian en quién puede fijar el límite de la potencia y la frecuencia — el hardware solo, o también vos. Y esa diferencia, no el clamshell, es lo que vale la pena contar.

El clamshell quedó como lo que era: el escenario que me obligó a medir. Lo uso de banco de pruebas, pero el tema es la comparación.

Cómo controla Intel: el límite lo escribís vos

En Intel, el techo de potencia es algo que escribís vos. RAPL (Running Average Power Limit) expone dos límites de potencia: PL1, el techo sostenido que el chip mantiene en el tiempo, y PL2, uno más alto que se permite por ráfagas cortas (el boost). Viven en el powercap framework del kernel —la interfaz bajo /sys/class/powercap para poner topes de potencia— y son de lectura/escritura:

echo 12000000 | sudo tee /sys/class/powercap/intel-rapl:0/constraint_0_power_limit_uw

Ese echo baja la potencia disponible y el PCU (Power Control Unit) del CPU la respeta. El hardware sigue teniendo su propia gestión térmica, pero ese tope es un control compartido: el sysadmin puede ponerlo por debajo del default de fábrica, y el procesador lo aplica.

Cómo controla AMD: el límite lo decide el firmware

En AMD ese control, sencillamente, no te lo dan. La rama de powercap puede existir —los Ryzen modernos exponen RAPL— pero con una diferencia decisiva:

En AMD, el RAPL del powercap reporta energía consumida (energy_uj), pero los archivos de límite de potencia (constraint_*_power_limit_uw) no se exponen. El máximo de potencia no se fija desde el sistema operativo.

No es un problema de permisos: el kernel no expone esa escritura para AMD por ninguna vía mainline (lo que viene de fábrica en el kernel oficial). Y hasta la lectura de energía está acotada: el energy_uj que aparece más abajo es legible solo por root desde el kernel 5.10, como mitigación de un ataque de canal lateral (PLATYPUS). Escritura del límite, en cambio, nunca hubo. El gobierno de la potencia y la frecuencia ocurre adentro del SMU (System Management Unit), el microcontrolador del SoC, que regula solo, en tiempo real, contra el primero de varios límites que se sature —potencia, corriente y temperatura—. El sistema operativo no hace esa regulación fina ni escribe el límite de potencia, pero tampoco es un espectador pasivo: le fija la política dentro de la cual optimizar —el gobernador, la preferencia de eficiencia o rendimiento (EPP) y el perfil de energía— y lee la telemetría.

Comprobalo en tu propia máquina. En vez de apuntar a un archivo puntual, listá el contenido de la zona del paquete y mirá qué hay:

cat /sys/class/powercap/intel-rapl:0/name
ls -l /sys/class/powercap/intel-rapl:0/

Dos cosas para notar. La primera: el dominio se llama intel-rapl aun en una máquina AMD. No es un error — el soporte RAPL de AMD se registra reusando el mismo framework y el mismo nombre que ya existía en el kernel. La segunda, y es el punto: en mi equipo Ryzen el name da package-0 y adentro solo hay energy_uj (el contador de energía consumida, de lectura). No existe ningún archivo constraint_* — ni constraint_0_power_limit_uw ni sus variantes. En un Intel, esa misma carpeta tendría los constraint_0_* (PL1) y constraint_1_* (PL2): los archivos donde se escribe el techo de potencia. En AMD el concepto de límite ni se expone. RAPL mide; no limita. Y es así por cómo está implementado el driver de AMD en mainline, no por una particularidad de este equipo —aunque no probé cada combinación de kernel y BIOS.

La evidencia: qué hace el firmware de AMD bajo carga

Medí el equipo AMD en clamshell y en AC —la condición real de un CPU box: tapa cerrada, en corriente, con un monitor de 14" apoyado encima bloqueando el aire— con un baseline en reposo y un stress de 20 minutos sostenidos (stress-ng --cpu 0), registrando temperatura de paquete (Tctl, el sensor que reporta AMD vía k10temp) y frecuencia.

En reposo, ~40 °C. Bajo carga, la temperatura sube despacio y se asienta cerca de 73 °C —todavía trepando muy de a poco al cabo de los 20 minutos—, mientras la frecuencia se mantiene alrededor de ~3,0 GHz toda la corrida, sin caídas abruptas:

22:59:54  temp=59.2°C  freq=3044.129MHz
23:05:30  temp=69.0°C  freq=3019.180MHz
23:10:25  temp=71.2°C  freq=3019.166MHz
23:19:42  temp=73.4°C  freq=3019.182MHz

Dos cosas para leer de ahí:

  1. El firmware sostiene un punto de operación estable de ~3,0 GHz con todos los núcleos cargados, sin que nadie intervenga. No es un techo que le puse yo: scaling_max_freq estaba en el máximo de fábrica. Es el SMU manteniendo la frecuencia que la potencia disponible le permite sostener.
  2. La temperatura se queda lejos de cualquier límite. 73 °C, lejos de su límite térmico —el Tjmax: la temperatura a la que el chip se frena o se apaga para no dañarse, del orden de 90–100 °C según el modelo de Ryzen—: margen de sobra. Y en 20 minutos no hubo una sola caída abrupta de frecuencia: el firmware regula y se queda quieto.

Qué significa la diferencia

Dos formas de repartir el control:

  • En Intel el control se reparte. El PCU regula, pero te deja escribir el techo de potencia en mainline (PL1/PL2): podés bajar el límite por debajo del default de fábrica y el procesador lo respeta. Queda compartido entre el hardware y vos. En el post Intel fijé PL1 bajo y tuned activo, y la frecuencia se sostuvo estable en clamshell — aunque, en realidad, apliqué las dos cosas juntas y no aislé cuánto aportó cada una.
  • En AMD el control queda en el firmware. El SMU regula de forma autónoma; el sistema operativo le marca una preferencia —hacia eficiencia o rendimiento, vía EPP y el perfil de energía— pero no le escribe el límite de potencia. Para ponerle un techo duro desde mainline, lo único que queda es la frecuencia (scaling_max_freq). Pero —y esto es lo que muestran las mediciones— el firmware ya está haciendo la regulación: en 20 minutos de carga sostuvo la frecuencia estable por su cuenta, sin que yo tocara nada.

De esto se sigue algo que va a contramano del reflejo de optimizar:

En este equipo AMD, bajar el techo de frecuencia no solo es innecesario (el firmware ya regula solo) — es contraproducente: le quitarías rendimiento que el chip podía sostener, sin ganar nada en seguridad térmica.

La receta de RAPL no se porta a AMD, y no solo porque la API sea distinta (el powercap de AMD solo expone telemetría, sin archivos de límite). Y el problema que la justificaba, en este hardware, tampoco existe: el firmware moderno de AMD gobierna el clamshell solo.

Si igual querés meter mano en AMD

Para cerrar, las dos vías reales y su estado:

  • Techo de frecuencia (scaling_max_freq, mainline). Es lo que el kernel te da, sin agregar nada, para ponerle un techo duro: un echo por core, persistible al boot (un profile de tuned o un service propio), sin tocar voltaje. Útil si tu equipo sí oscila o si querés sacrificar rendimiento a propósito por un equipo más fresco. Por lo que vimos, para seguridad térmica acá sobra.
  • El tope de potencia (PPT vía ryzenadj). Es la forma de llegar a ese tope del SMU desde el sistema —los límites que AMD llama PPT (Package Power Tracking, el tope de potencia del paquete) y STAPM (atado a la temperatura de la carcasa)— pero queda fuera de mainline: ryzenadj (LGPL-3.0) se compila a mano y necesita el módulo ryzen_smu (GPL-2.0), que vive out-of-tree —fuera del árbol del kernel— y hay que recompilar en cada actualización (eso lo automatiza DKMS), además de pelear con Secure Boot. Es libre y se usa en producción en handhelds (Bazzite, Steam Deck), pero es tooling de entusiasta, no de infraestructura. Y es justamente la prueba de la tesis: el control que Intel expone en mainline, en AMD hay que buscarlo fuera del árbol. Nada de esto es peligroso —es runtime, no flashea firmware, un reboot revierte todo— pero para un CPU box que tiene que comportarse como infraestructura, el costo no se justifica.

Contrastar la premisa y después medir

El reflejo sería asumir que el setup Intel se porta cambiando una ruta de /sys. Pero la premisa hay que contrastarla, y no es la misma en los dos fabricantes: en AMD el archivo para establecer un límite ni siquiera está. Contrastarla a tiempo es lo que evita el desvío siguiente —buscar la herramienta que sí escribe watts y terminar en ryzenadj con un módulo out-of-tree—. Y antes de salir a buscar esa herramienta, conviene medir: acá la medición mostró que no había nada que arreglar.

La diferencia de arquitectura entre Intel y AMD define si te toca intervenir o si el firmware ya lo hace.

Lo que me llevo

  • Intel y AMD difieren en quién escribe el límite de potencia: Intel te lo deja en mainline (RAPL r/w); AMD lo retiene en el SMU —desde el SO le marcás una preferencia (eficiencia o rendimiento) y leés energía, pero el tope no lo escribís—.
  • En AMD, el firmware sostiene una frecuencia estable por su cuenta (~3,0 GHz en 20 min de carga) y la temperatura se queda con margen de sobra respecto del Tjmax. Sin oscilación ni throttling.
  • En AMD el tope de potencia (PPT) no se escribe en mainline —solo con tooling out-of-tree (ryzenadj)—; en mainline tenés la política (EPP, perfil de energía) y un techo por la frecuencia (scaling_max_freq), pero no el límite de watts directo. Es la contracara exacta de lo que Intel expone de fábrica.
  • Antes de optimizar, medir: en este equipo, bajar el techo habría sido contraproducente.
  • tuned cruza sin cambios entre plataformas — solo cambia el driver de scaling debajo (amd_pstate en vez de intel_pstate).

Fuentes

Documentación oficial y mediciones en el propio equipo.

Documentación oficial

Verificado en el equipo

  • Que el powercap de AMD solo expone energy_uj y ningún constraint_*, y la jerarquía package-0/core: los comandos cat/ls sobre /sys/class/powercap/ que están en el cuerpo. El driver (amd-pstate-epp) y las palancas de política (EPP, platform_profile) se leen read-only de /sys/devices/system/cpu/cpufreq/ y /sys/firmware/acpi/.
  • Que el firmware sostiene la frecuencia sin intervención: baseline y stress de 20 minutos, reproducibles con stress-ng --cpu 0 y la lectura de Tctl (k10temp).

Comentarios

Comments powered by Disqus