IT-Admin.tech

Ottimizzazione energetica nel centro dati: governor della frequenza CPU, C-States e il loro impatto sulla latenza

Admin analysiert CPU-C-States und Frequenzskalierung an Server-Hardware und Diagramm im Rechenzentrum
Energiepolitik der CPU ist messbar: Residency, Frequenzverhalten und Wakeup-Pfade entscheiden über Tail-Latenz.

L‘ottimizzazione energetica nel centro dati non è più solo una questione di costi. Influisce sulla stabilità termica, sulla durata dell’hardware, sulla densità per rack e, non da ultimo, sulla prevedibilità delle prestazioni. Nella pratica spesso è una combinazione apparentemente insignificante di regolazione della frequenza della CPU (CPU-Freq-Governors) e stati di sospensione della CPU (C-States, cioè Idle-States) a determinare se i sistemi risultano „sazi“ e prevedibili oppure se compaiono improvvisi picchi di latenza difficili da riprodurre.

Questo articolo inquadra chiaramente i meccanismi e li traduce in decisioni operative: cosa si può risparmiare senza rischi? Dove aumenta il rischio di jitter (variazioni nei tempi di risposta)? E come intervenire in particolare negli ambienti Kubernetes, in cui molti carichi di lavoro condividono gli host ma singole applicazioni hanno comunque requisiti di latenza stringenti?

Ottimizzazione energetica nel centro dati nella pratica

Sulle CPU dei server moderni ci sono due leve di intervento principali:

  • Scalatura frequenza/tensione tramite P-States (Performance-States): la CPU incrementa o diminuisce il clock, spesso accoppiato alla tensione di alimentazione. Un CPU-Freq-Governor è la policy che decide quanto aggressivamente scalare verso l’alto o verso il basso.
  • Stati di sospensione idle tramite C-States: quando un core non ha lavoro, può passare a stati di sospensione progressivamente più profondi. Più profondo è il C-State, maggiore è il risparmio energetico, ma tipicamente più lungo è il tempo di risveglio (Exit Latency).

Il fraintendimento in esercizio: „più risparmio = sempre più lento“. In realtà la situazione è più sfumata. Molti carichi di lavoro non sono mediamente limitati dalla CPU, ma beneficiano di alta efficienza finché le latenze di coda (ad es. il 99° percentile) non sfuggono al controllo. Diventa critico soprattutto quando il carico è bursty (picchi brevi e frequenti), oppure quando singoli thread/request devono essere serviti molto rapidamente e la transizione da un C-State profondo o da una frequenza bassa al „pieno regime“ ricade proprio in quel periodo.

Altri fattori tipici che amplificano il fenomeno nel centro dati sono: NUMA (Non-Uniform Memory Access, cioè tempi di accesso alla memoria non uniformi a seconda del socket CPU), interrupt condivisi, Hyper-Threading/SMT (due thread condividono le risorse di un core) e virtualizzazione/containerizzazione con assegnazione di CPU variabile.

CPU-Freq-Governors, P-States e driver: cosa gli amministratori devono sapere davvero

Sotto Linux il sottosistema di gestione della frequenza della CPU si è sviluppato storicamente. È determinante quale driver è attivo, perché il driver definisce le possibilità di controllo reali e l’osservabilità. Varianti comuni:

  • intel_pstate: driver specifico Intel, spesso predefinito. Usa DVFS interno all’hardware/CPU (Dynamic Voltage and Frequency Scaling) e offre policy come “performance”/“powersave”. I nomi possono trarre in inganno: “powersave” significa qui spesso “gestito dall’hardware, efficiente” e non è necessariamente “lento”.
  • amd_pstate: equivalente AMD su piattaforme recenti, con maturità variabile a seconda di kernel/BIOS.
  • acpi-cpufreq: driver generico basato su ACPI, offre governor classici come “ondemand”, “conservative” ecc.

La policy del governor determina quanto rapidamente si reagisce al carico. In molte configurazioni di centro dati i tempi di risposta (ramp-up) sono più importanti della frequenza massima. Questo significa: una policy che scala rapidamente verso l’alto può stabilizzare le latenze di coda, senza restare permanentemente al massimo clock.

Rapida rilevazione su Linux-Hosts

Per stabilire una baseline affidabile dovreste prima rilevare driver, governor e limiti di frequenza. A questo scopo utilizzate cpupower (nome del pacchetto a seconda della distribuzione):

Shell
# Überblick: Treiber, Governor, aktuelle Frequenz, Grenzen
cpupower frequency-info

# Kurzstatus pro CPU (je nach Distribution verfügbar)
cpupower frequency-info -p

Inoltre conviene dare un’occhiata a sysfs (utile per automazione/CMDB):

Shell
# Treiber und Governor pro CPU (CPU0 als Beispiel)
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_driver
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor

# Grenzen (kHz)
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq

Trappola tipica: le impostazioni del BIOS possono sovrascrivere o limitare Linux (p.es. “Energy Efficient Turbo”, “C-State Control”, “Package C-State Limit”, “Power Regulator”). Se agite a livello OS ma il BIOS o il controller di gestione impongono limiti stringenti, vedrete politiche apparentemente „corrette“ ma senza effetto.

Comprendere gli C-States: Core vs. Package e la latenza di exit

Grafico senza testo: package CPU con stati Core- e Package-Idle e percorso di risveglio
Core- vs. Package-Idle: un Package-Idle più profondo può comportare tempi di risveglio più lunghi.

Gli C-State sono stati di idle. Un core può passare da C1 (molto superficiale) fino a stati più profondi. Inoltre esistono i Package C-States, in cui l’intero socket CPU (il “Package”) entra in uno stato di sleep più profondo quando un numero sufficiente di core è idle. Proprio questi stati di Package sono spesso la fonte di picchi di latenza difficili da spiegare, perché il risveglio coinvolge più componenti (uncore, gerarchia di cache, interconnect).

La domanda operativa rilevante non è «quali C-State sono abilitati?», bensì: con quale frequenza e per quanto tempo risiede la CPU in quali C-State, e le latenza di exit sono correlate ai vostri SLO (Service Level Objectives)?

Misurare la residency degli C-State

Su Linux turbostat (parte dei linux-tools) fornisce indicazioni utili. Mostra, tra l’altro, la percentuale di residency nei C-State e il comportamento di frequenza/turbo. Esempio:

Shell
# 10 Messzyklen à 1 Sekunde, kompakt
turbostat --quiet --Summary --interval 1 --num_iterations 10

Se durante le fasi in cui si manifestano picchi di latenza osservate un’elevata residency in profondi Package-State, è un forte indizio. Viceversa: se la CPU raramente scende al di sotto di C1/C2 (p.es. a causa di carico di background, interrupt, agent di monitoraggio), un tuning aggressivo degli C-State spesso porta a scarsi risultati — la causa è altrove (scheduler, tempeste di IRQ, storage, rete).

Sintomi tipici di latenza coerenti con governor/C-State

Non ogni latenza è un problema “power”. Tuttavia i seguenti pattern corrispondono spesso a temi di frequenza e idle:

  • Picchi nell’ordine dei millisecondi con latenza media altrimenti stabile, spesso su richieste bursty (API-Gateways, Ingress, Auth, percorsi di cache-miss).
  • Cluster di jitter regolari a intervalli di secondi, che correlano con i cicli di idle/wakeup.
  • Solo determinati nodi sono interessati (profilo BIOS diverso, diversa versione di microcode/kernel, diversi limiti di potenza).
  • Il problema scompare sotto carico continuo (perché la CPU non entra più in idle profondo) e si manifesta nelle fasi „tranquille“.

Importante: questi sintomi possono derivare anche da IRQ-Balancing, accessi remoti NUMA, quota CPU di cgroup, CPU-Steal (in virtualizzazione) o pause del garbage collector. Perciò è centrale una strategia di misurazione e di esclusione.

Workflow pratico: dall’ipotesi a una decisione fondata

Operatore confronta curve di misura e assorbimento energetico su un server di test nel centro dati
Misurazione prima della modifica: latenza, frequenza e tempo di permanenza in idle dovrebbero essere considerate insieme.

Un processo solido nel centro dati richiede riproducibilità, telemetria e rollback. Un flusso operativo collaudato:

  1. Classificare il workload: sensibile alla latenza (es. servizi vicini al realtime), orientato al throughput (batch), misto (API con picchi).
  2. Definire SLO e punti di misura: latenza p95/p99, lunghezze delle code, Error-Budget, inoltre energia/temperatura (se disponibile).
  3. Misurare la baseline: turbostat, cpupower, carico di sistema, tassi IRQ, runqueue dello scheduler, metriche di Kubernetes.
  4. Modifica minimamente invasiva e solo su nodi selezionati (Canary): es. cambiare il governor o limitare i C-States.
  5. Confronto con la baseline: stessi profili di carico, stessi intervalli temporali, stessa metodologia di misura.
  6. Preparare il rollback: parametri OS/Boot ripristinati, profilo BIOS documentato, playbook di automazione aggiornati.

Implementazione su Linux: impostare il governor, definire limiti, garantire la persistenza

Per molti workload server il punto di partenza pragmatico è: governor „performance“ sui nodi critici per la latenza, e una modalità di policy hardware efficiente (a seconda del driver) sui nodi generali. Ciò che conta è la differenziazione dei nodi, non un dogma globale.

Impostare temporaneamente il governor (Test)

Shell
# Performance-Policy für alle CPUs (temporär bis Reboot/Policy-Reset)
cpupower frequency-set -g performance

# Alternativ: powersave (bei intel_pstate oft "hardware-managed")
cpupower frequency-set -g powersave

Se cpupower fallisce, spesso è dovuto a permessi mancanti (sudo), moduli/strumenti assenti o al fatto che il driver non offre i governor classici (es. a seconda della modalità intel_pstate). Verifichi allora cosa cpupower frequency-info segnala come „available governors“.

Configurazione persistente con tuned (famiglia RHEL-/CentOS-/Rocky-/Alma)

tuned è un daemon che applica profili per Power/Performance. Per l’esercizio operativo questo è spesso più stabile rispetto a script individuali, perché considera le sequenze di avvio/servizi.

Shell
# Status und aktives Profil
tuned-adm active

# Beispiel: auf Performance schalten (Host-weit)
tuned-adm profile performance

Trappola: tuned può anche modificare IRQ-Balancing, impostazioni del disco o parametri di rete. Per un tuning mirato della CPU è consigliabile un profilo personalizzato che imposti solo le leve necessarie, invece di adottare ciecamente un ampio profilo standard.

Limitare i C-States: utile, rischioso, a volte necessario

Limitare i C-States è una leva rozza ma efficace quando le exit-latencies dominano la latenza di coda. Tecnicamente si interviene spesso tramite parametri di avvio del kernel o limiti nel BIOS. Questo riduce il potenziale di risparmio energetico ma può stabilizzare la latenza.

Parametri di avvio del kernel (esemplificativi) e possibilità di rollback

Quali parametri siano sensati dipende da piattaforma e kernel. Le regolazioni utilizzate più frequentemente sono:

  • intel_idle.max_cstate: limita i C-States massimi nel driver intel_idle.
  • processor.max_cstate: parametro generico di limite (agisce in modo diverso a seconda del driver).
  • idle=poll: impedisce stati di idle profondi (molto dispendioso in energia, da usare più come strumento diagnostico).

Applichi questi parametri inizialmente su un Canary-Node e documenti lo stato preciso prima/dopo. Esempio per GRUB (le distribuzioni differiscono; verifichi i suoi standard):

Shell
# 1) Aktuelle Kernel-Cmdline prüfen
cat /proc/cmdline

# 2) GRUB Default anpassen (Beispiel)
sudo sed -i 's/GRUB_CMDLINE_Linux="/GRUB_CMDLINE_Linux="intel_idle.max_cstate=1 processor.max_cstate=1 /' /etc/default/grub

# 3) GRUB-Konfig regenerieren (Pfad je nach Distribution)
sudo grub2-mkconfig -o /boot/grub2/grub.cfg

# 4) Reboot planen und nach dem Boot wieder prüfen
sudo reboot

Il rollback è identico: rimuovere i parametri, rigenerare GRUB, effettuare il reboot. Pianifichi una finestra di manutenzione, poiché si tratta di una modifica a livello di boot.

Importante per la decisione: se limita i C-States, monitori anche temperatura, curve delle ventole e power limits. In ambienti densi questo può avere effetti secondari (thermal throttling) che alla fine penalizzano di nuovo le prestazioni — ma in modo diverso.

Specifico per Kubernetes: tuning dei nodi senza effetti collaterali

Textfreie Grafik: Kubernetes-Cluster mit getrennten Node-Pools für Low-Latency und Batch
Separare i node-pool per SLO: il tuning per low-latency solo dove è necessario.

In Kubernetes la questione si complica, perché i carichi di lavoro sono distribuiti dinamicamente. L’ottimizzazione energetica e la stabilità della latenza non sono qui un esercizio di “tuning fine dell’host”, ma una questione di ruoli dei nodi, scheduling e isolamento.

Principio di base: pool di nodi diversi per SLO diversi

Se mischia workload sensibili alla latenza (per es. Ingress, Service-Mesh-Data-Plane, Auth, frontend di message-broker) e Batch/CI/ETL sugli stessi nodi, ogni policy energetica diventa un compromesso. Meglio:

  • Node-Pool „low-latency“: meccanismi di risparmio energetico conservativi (policy con maggior performance, C-States limitati), isolamento CPU più rigoroso.
  • Node-Pool „balanced“: policy efficienti, ma con monitoraggio sulla latenza di coda.
  • Node-Pool „batch“: massima efficienza energetica, a fronte di una maggiore tolleranza al jitter.

Questa separazione la implementate tramite Labels/Taints/Tolerations (Label = criterio, Taint = „solo con autorizzazione“). Questo impedisce che un singolo Deployment detti le vostre globali CPU-Policies.

CPU-Manager, Cgroups und „Guaranteed“-Pods

Il Kubelet CPU Manager può assegnare core in esclusiva ai Pod (policy „static“). Questo riduce lo scheduler-jitter perché un Pod non viene continuamente migrato tra le CPU. Condizione tipica sono i Guaranteed Pods (Requests = Limits) per CPU. Le cgroups (Control Groups, controllo delle risorse nel kernel) applicano i limiti; con cgroup v2 alcuni dettagli sono diversi, ma il principio rimane.

Per un primo controllo: quale versione di cgroup usano i vostri nodi?

Shell
stat -fc %T /sys/fs/cgroup

E se il CPU Manager è attivato (la configurazione del Kubelet dipende dal cluster). Su molti sistemi trovate la configurazione per esempio in /var/lib/kubelet/config.yaml:

Shell
sudo grep -E "cpuManagerPolicy|cpuManagerReconcilePeriod" -n /var/lib/kubelet/config.yaml || true

Trappola tipica: CPU-Manager „static“ serve a poco se contemporaneamente la frequenza CPU viene risparmiata in modo aggressivo o se i profondi Package C-States restano attivi. I core esclusivi riducono le migrazioni, ma non la latenza di risveglio da idle profondo. Per nodi a bassa latenza questi aspetti devono essere considerati congiuntamente.

IRQ-Affinität und „Noisy Neighbors“

Gli interrupt (IRQs) sono eventi hardware che consumano tempo CPU al di fuori dei normali processi. Se su un core “esclusivo” finiscono comunque molti IRQ da NIC o storage, l’isolamento diventa di fatto inutile. Verificate quindi il carico e la distribuzione degli IRQ:

Shell
# IRQ-Statistik (Momentaufnahme)
cat /proc/interrupts | head -n 30

# Softirqs (Netzwerk/Block-Processing im Kernel)
cat /proc/softirqs | head -n 30

In Kubernetes un trigger frequente è: Node-Local-DNS, CNI (Container Network Interface) e plugin di storage che generano traffico di background elaborato su CPU “sbagliate”. A seconda della piattaforma possono aiutare la configurazione di irqbalance, i CPU-set e una chiara separazione tra „System-Cores“ e „Workload-Cores“ (per es. tramite isolcpus/nohz_full come opzioni avanzate). Queste azioni sono invasive e dovrebbero essere eseguite solo con un piano di test e rollback ben definito.

Checkliste: Vor dem Tuning prüfen (damit Sie nicht das Falsche optimieren)

  • BIOS/UEFI: profili di alimentazione, limiti di C-State, Turbo, SMT, opzioni per performance deterministiche. Documentate lo stato per ogni modello di nodo.
  • Mikrocode und Kernel: stati diversi modificano in modo misurabile il comportamento di power e idle. Uniformateli prima di confrontare.
  • Virtualisierung: nelle VM il CPU-Steal/la policy dell’host è spesso più determinante del tuning del guest. In questo articolo si tratta primariamente di Bare Metal o Host-OS.
  • Monitoring: misurate p95/p99 e non solo la media; correlate con CPU-Idle-Residency, frequenza e tassi di IRQ.
  • Lastprofil: il tuning sotto carico continuo sintetico può non rispecchiare il comportamento reale in burst.

Troubleshooting: Wenn nach dem Tuning neue Probleme auftauchen

Symptom: Höhere Temperaturen, aber keine bessere Latenz

Dann ist häufig nicht C-State-Exit die Ursache, sondern Queueing an anderer Stelle (Netzwerk, Storage, Lock-Contention) oder Thermal Throttling. Prüfen Sie, ob die CPU unter Last taktet wie erwartet und ob Power-Limits greifen. Bei vielen Servern liefern BMC/Redfish oder Hersteller-Tools die nötigen Werte; auf OS-Ebene hilft turbostat als Indikator.

Symptom: Mehr Durchsatz, aber schlechtere Tail-Latenz

Das deutet oft auf „zu aggressive“ Boost-/Turbo-Phasen hin, die in thermische Limits laufen, oder auf mehr Konkurrenz durch Background-Tasks (z. B. weil alles schneller wird, aber auch mehr parallel passiert). In Kubernetes: Prüfen Sie Pod-Dichte pro Node, CPU-Throttling (cgroup) und ob QoS-Klassen sauber gesetzt sind.

Symptom: Nur einzelne Pods sind betroffen

Dann sind CPU-Policies meist nur ein Faktor. Häufige Ursachen sind CPU-Quota/Throttling (Limits), ungünstige CPU-Affinitäten, GC-Pausen (bei JVM/.NET), oder „Noisy Neighbor“-Effekte durch Shared Caches/SMT. Für Latenz-kritische Pods sollten Sie Requests/Limits konsistent setzen und, wenn nötig, auf dedizierte Nodes ausweichen.

Rückfallstrategie: Wie Sie sicher wieder auf den Ausgangszustand kommen

Eine Rückfallstrategie ist keine Formalität, sondern der Unterschied zwischen kontrolliertem Experiment und nächtlicher Eskalation. Planen Sie mindestens diese Ebenen:

  • OS-Policy Rollback: Governor zurücksetzen (cpupower/tuned), Services neu laden, dokumentierter Sollzustand in Konfigurationsmanagement.
  • Boot-Parameter Rollback: GRUB-Änderungen revertieren, alte Kernel-Cmdline verfügbar halten, im Zweifel per Boot-Menü starten.
  • Node-Pool Rollback in Kubernetes: Canary-Nodes aus dem Pool nehmen (cordon/drain), Workloads zurück auf „balanced“ verschieben, dann erst weiter ändern.

Für Kubernetes-Operationen (Canary/Drain) als Standardwerkzeugkasten:

Shell
# Node für neue Pods sperren
kubectl cordon <node-name>

# Pods kontrolliert evakuieren (Achtung: PDBs und Stateful Workloads)
kubectl drain <node-name> --ignore-daemonsets --delete-emptydir-data

# Nach Rollback wieder freigeben
kubectl uncordon <node-name>

Stolperfalle: Drain kann an PodDisruptionBudgets (PDB) oder lokalen Daten (emptyDir) scheitern. Das ist kein „Kubernetes-Problem“, sondern Teil der Betriebsrealität – und genau deshalb sollten Sie Power-/Latency-Tuning als kontrollierten Node-Pool-Prozess behandeln.

Best Practices: Energieeffizienz und Latenz stabil zusammenbringen

  • Segmentieren statt global schrauben: Unterschiedliche Policies pro Node-Pool sind fast immer besser als ein Cluster-weiter Kompromiss.
  • Messen Sie Residency, nicht nur Watt: C-State- und Frequenz-Metriken erklären Latenzspitzen oft besser als reine Leistungsaufnahme.
  • Erst Treiber/BIOS vereinheitlichen: Ohne reproduzierbare Basis sind Vergleiche wertlos.
  • IRQ- und CPU-Isolation für Low-Latency: Exklusive Cores, System-Cores, IRQ-Affinität – aber nur mit sauberem Change-Management.
  • Rollback als Runbook: Ein Tuning ohne Rückweg ist im Rechenzentrum nicht produktionsreif.

Fazit: Energieoptimierung ist ein Betriebsdesign, kein Schalter

L’ottimizzazione energetica nel data center è sostenibile se si comprendono i governor della frequenza della CPU, i P-States e i C-States come parte di un design operativo: ruoli dei nodi, Kubernetes-Scheduling, metodica di misurazione e strategia di fallback appartengono insieme. Per carichi di lavoro generici il ridimensionamento efficiente dell’hardware è spesso poco critico. Per servizi critici per la latenza, invece, è opportuno adottare politiche più conservative, limitare gli idle profondi e applicare con coerenza l’isolamento (CPU/IRQ) — non ovunque, ma dove tutela davvero gli SLO.

Se desiderate affrontare l’argomento in modo sistematico nel vostro ambiente, pianificate come prossimo passo un Canary-Pool, definite criteri di misurazione (p95/p99 + Residency) e documentate i parametri BIOS/Kernel per piattaforma. Così ciò che è ‚percepito più veloce‘ diventa una decisione solida e operativamente sicura.

Weiterfuehrend

Passende weitere Inhalte