00 cpufreq nedir — DVFS ve kernel subsystem
cpufreq, Linux kernel'ın CPU voltaj ve frekansını çalışma zamanında dinamik olarak yöneten alt sistemidir. Temel fikir: düşük yük altında frekansı (ve voltajı) düşürerek güç tüketimini kare-küp ilişkisiyle azaltmak.
Güç tüketimi dinamik bileşeni şu formülle özetlenir: P = C × V² × f. Frekansı yarıya indirmek voltajı da düşürmeye olanak tanır; voltajdaki küçük bir düşüş güçte dramatik azalma sağlar. Bu ilkeye DVFS (Dynamic Voltage & Frequency Scaling) denir.
Kernel subsystem mimarisi
┌─────────────────────────────────────────────┐
│ userspace / sysfs │
│ /sys/devices/system/cpu/cpu0/cpufreq/ │
├─────────────────────────────────────────────┤
│ cpufreq core (kernel) │
│ governor → policy → driver │
├──────────────┬──────────────────────────────┤
│ cpufreq │ cpufreq driver │
│ governor │ (platform-specific) │
│ (schedutil) │ intel_pstate / acpi-cpufreq │
│ │ cpufreq-dt / arm_big_little │
├──────────────┴──────────────────────────────┤
│ clock subsystem (clk_set_rate) │
│ regulator subsystem (regulator_set_v) │
└─────────────────────────────────────────────┘
sysfs arayüzü — temel dosyalar
# CPU0 cpufreq dizini
ls /sys/devices/system/cpu/cpu0/cpufreq/
# affected_cpus cpuinfo_cur_freq cpuinfo_max_freq cpuinfo_min_freq
# cpuinfo_transition_latency related_cpus scaling_available_governors
# scaling_available_frequencies scaling_cur_freq scaling_driver
# scaling_governor scaling_max_freq scaling_min_freq scaling_setspeed
# mevcut frekans (kHz)
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
# 1500000
# aktif governor
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
# schedutil
# donanımın desteklediği frekanslar
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies
# 600000 900000 1200000 1500000 1800000
cpufreq-dt, intel_pstate).Intel Turbo Boost veya AMD Precision Boost aktifken cpuinfo_cur_freq, cpuinfo_max_freq'i aşabilir. Bu normal bir davranıştır — turbo aralığı sysfs üzerinden ayrıca yönetilir.
01 Governor'lar — performance'dan schedutil'e
Governor, anlık CPU yüküne bakarak hangi frekansın seçileceğine karar veren politika motorudur. Doğru governor seçimi güç/performans dengesini doğrudan belirler.
scaling_setspeed dosyasına yaz. Test ve özel politikalar için.Governor değiştirme
# tüm CPU'larda schedutil'e geç
for cpu in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do
echo schedutil > "$cpu"
done
# ya da cpupower ile
cpupower frequency-set -g schedutil
# ondemand parametrelerini ayarla
ls /sys/devices/system/cpu/cpufreq/ondemand/
# ignore_nice_load powersave_bias sampling_down_factor
# sampling_rate sampling_rate_min up_threshold
# örnekleme hızını artır (ms cinsinden, mikrosaniye değil)
echo 50000 > /sys/devices/system/cpu/cpufreq/ondemand/sampling_rate
# schedutil için rate_limit_us ayarı
cat /sys/devices/system/cpu/cpufreq/schedutil/rate_limit_us
# 1000 (1ms — frekans değişim hızı sınırı)
Governor seçim rehberi
Gerçek zamanlı / düşük gecikme → performance
Pil ömrü öncelikli (IoT, sensor) → powersave veya schedutil
Genel amaçlı masaüstü/sunucu → schedutil (Linux 4.7+)
big.LITTLE / EAS etkin sistem → schedutil (zorunlu)
Eski çekirdek (< 4.7) → ondemand
Enerji profili / test → userspace
ondemand ve conservative governor'ları tickless (NO_HZ_IDLE) kernel ile birlikte kullanıldığında, CPU boşta iken timer tick'i azaldığından örnekleme gecikmesi artabilir. schedutil bu sorunu yaşamaz çünkü scheduler event'lerine doğrudan bağlıdır.
02 OPP — Operating Performance Points
OPP tablosu, CPU'nun çalışabileceği voltaj-frekans çiftlerini tanımlar. Device Tree'de tanımlanan bu tablo, cpufreq driver'ının hangi adımları kullanabileceğini belirler.
Device Tree OPP tanımı
/ {
cpu0_opp_table: opp-table-0 {
compatible = "operating-points-v2";
opp-shared; /* tüm CPU'lar aynı tabloyu paylaşır */
opp-600000000 {
opp-hz = /bits/ 64 <600000000>; /* 600 MHz */
opp-microvolt = <950000>; /* 0.95 V */
clock-latency-ns = <300000>;
};
opp-900000000 {
opp-hz = /bits/ 64 <900000000>; /* 900 MHz */
opp-microvolt = <1025000>; /* 1.025 V */
};
opp-1200000000 {
opp-hz = /bits/ 64 <1200000000>; /* 1.2 GHz */
opp-microvolt = <1100000>; /* 1.1 V */
};
opp-1500000000 {
opp-hz = /bits/ 64 <1500000000>; /* 1.5 GHz */
opp-microvolt = <1200000>; /* 1.2 V */
turbo-mode; /* turbo OPP */
};
};
cpus {
cpu@0 {
compatible = "arm,cortex-a53";
operating-points-v2 = <&cpu0_opp_table>;
clocks = <&ccu CLK_CPU>;
clock-names = "cpu";
cpu-supply = <®_vdd_cpu>; /* regulator bağlantısı */
};
};
};
OPP ile ilgili sysfs/debugfs
# OPP tablosunu debugfs'ten oku
cat /sys/kernel/debug/opp/cpu0/opp_summary
# OPP: 600000000 Hz, 950000 uV
# OPP: 900000000 Hz, 1025000 uV
# OPP: 1200000000 Hz, 1100000 uV
# OPP: 1500000000 Hz, 1200000 uV [turbo]
# scaling_available_frequencies ile kontrol et
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies
# 600000 900000 1200000 1500000
devfreq ile fark
cpufreq yalnızca CPU'lar içindir. devfreq, GPU, DDR bellek, görüntü işleme birimi (ISP) gibi diğer donanım blokları için benzer bir DVFS altyapısı sağlar. Her ikisi de OPP tablosunu kullanır; ancak devfreq kendi governor'larına (simple_ondemand, powersave, performance, userspace) sahiptir.
# devfreq cihazlarını listele (GPU, DDR vb.)
ls /sys/class/devfreq/
# ff400000.gpu ff610000.dmc
cat /sys/class/devfreq/ff400000.gpu/cur_freq
# 400000000
03 sysfs ile manuel kontrol
Governor'ı userspace olarak ayarlayıp scaling_setspeed'e yazmak, tam manuel kontrol sağlar. Test, profil alma ve özel enerji politikaları için kullanışlıdır.
# CPU0'ı manuel moda al
echo userspace > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
# frekansı 900 MHz'e sabitle (kHz cinsinden)
echo 900000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed
# doğrula
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
# 900000
# frekans aralığını kısıtla (governor hâlâ aktifken)
echo 600000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq
echo 1200000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq
# tüm CPU'larda aynı anda uygula
for i in $(seq 0 3); do
echo 1200000 > /sys/devices/system/cpu/cpu$i/cpufreq/scaling_max_freq
done
cpufreq-set (cpufrequtils paketi)
# cpufreq-set ile governor değiştir
cpufreq-set -c 0 -g schedutil # CPU0
cpufreq-set -g ondemand # tüm CPU'lar
# frekans aralığını ayarla
cpufreq-set -c 0 -d 600MHz -u 1.2GHz
# sabit frekans (userspace governor otomatik seçilir)
cpufreq-set -c 0 -f 900MHz
# mevcut ayarları göster
cpufreq-info -c 0
Gömülü sistemlerde önyükleme sırasında governor ayarlamak için /etc/default/cpufrequtils dosyasına GOVERNOR="schedutil" yazabilir veya systemd service dosyasından cpupower frequency-set -g schedutil çalıştırabilirsin.
04 Energy-Aware Scheduling (EAS)
Linux 5.0 ile kararlı hale gelen EAS, görevleri yalnızca boş CPU'ya değil, enerji maliyeti en düşük CPU'ya atayan bir scheduler özelliğidir. big.LITTLE mimarisinin gücünü tam olarak açığa çıkarır.
EAS gereksinimleri
cpu-capacity DT özelliği veya cpufreq ile belirlenir.Energy Model DT tanımı
/* Cortex-A55 (LITTLE cluster) */
cpu@0 {
compatible = "arm,cortex-a55";
capacity-dmips-mhz = <406>; /* normalize kapasite */
dynamic-power-coefficient = <100>;
};
/* Cortex-A76 (big cluster) */
cpu@4 {
compatible = "arm,cortex-a76";
capacity-dmips-mhz = <1024>;
dynamic-power-coefficient = <530>;
};
EAS aktif mi kontrol et
# EAS durumunu göster
cat /proc/sys/kernel/sched_energy_aware
# 1 = aktif
# Energy Model var mı?
ls /sys/kernel/debug/energy_model/
# cpu0 cpu4
cat /sys/kernel/debug/energy_model/cpu0/table
# cap freq power
# 73 500000 50
# 146 1000000 90
# 219 1500000 145
# EAS'ı geçici olarak kapat
echo 0 > /proc/sys/kernel/sched_energy_aware
EAS etkin bir big.LITTLE sistemde, hafif görevler LITTLE çekirdeklere atanır; ağır anlık görevler big çekirdeklere geçer. Bu mekanizma, aynı işi yaparken %20-40 daha az enerji tüketebilir.
05 Boost ve turbo frekans
Turbo/boost, kısa süreli anlık yükler için OPP tablosundaki maksimum frekansın üzerine çıkma yeteneğidir. Platform bağımlıdır; her mimaride farklı uygulanır.
Generic boost (ARM / cpufreq-dt)
# boost durumunu göster
cat /sys/devices/system/cpu/cpufreq/boost
# 1 = etkin
# boost'u devre dışı bırak
echo 0 > /sys/devices/system/cpu/cpufreq/boost
# tekrar etkinleştir
echo 1 > /sys/devices/system/cpu/cpufreq/boost
Intel P-state
# Intel P-state sürücüsü ile turbo kontrolü
cat /sys/devices/system/cpu/intel_pstate/no_turbo
# 0 = turbo etkin, 1 = kapalı
echo 1 > /sys/devices/system/cpu/intel_pstate/no_turbo
# enerji/performans tercihi (EPP)
cat /sys/devices/system/cpu/cpu0/cpufreq/energy_performance_preference
# balance_performance
# mevcut seçenekler
cat /sys/devices/system/cpu/cpu0/cpufreq/energy_performance_available_preferences
# default performance balance_performance balance_power power
echo power > /sys/devices/system/cpu/cpu0/cpufreq/energy_performance_preference
AMD P-state
# AMD P-state modu (Linux 5.17+)
cat /sys/devices/system/cpu/amd_pstate/status
# active (passive veya guided olabilir)
# AMD P-state EPP (Linux 6.3+)
cat /sys/devices/system/cpu/cpu0/cpufreq/amd_pstate_epp
# balance_performance
ARM tabanlı gömülü sistemlerde (Raspberry Pi, i.MX, RK3568 vb.) "turbo" kavramı OPP tablosundaki en yüksek OPP'yi ifade eder; ayrı bir turbo mekanizması yoktur. Termal throttling aktif olduğunda bu OPP otomatik olarak devre dışı kalır.
06 cpupower araçları
cpupower, cpufreq sysfs arayüzü için kapsamlı bir komut satırı aracıdır. Hem frekans yönetimi hem de güç tüketimi izleme özellikleri sunar.
Kurulum ve temel kullanım
# Ubuntu/Debian
apt install linux-tools-$(uname -r) cpufrequtils
# Fedora/RHEL
dnf install kernel-tools
# tüm CPU'ların frekans bilgisi
cpupower frequency-info
# analyzing CPU 0:
# driver: cpufreq-dt
# CPUs which run at the same hardware frequency: 0
# hardware limits: 600 MHz - 1.50 GHz
# available frequency steps: 600 MHz, 900 MHz, 1.20 GHz, 1.50 GHz
# available cpufreq governors: conservative ondemand userspace
# powersave performance schedutil
# current policy: frequency should be within 600 MHz and 1.50 GHz.
# The governor "schedutil" may decide which speed to use
# current CPU frequency: 900 MHz (asserted by call to hardware)
Frekans ayarlama
# governor değiştir (tüm CPU'lar)
cpupower frequency-set -g performance
# maksimum frekansı sınırla
cpupower frequency-set -u 1.2GHz
# minimum frekansı ayarla
cpupower frequency-set -d 900MHz
# belirli CPU için
cpupower -c 2 frequency-set -g powersave
cpupower monitor — güç monitörleme
# mevcut monitor'leri listele
cpupower monitor -l
# Monitor "Mperf" (3 states) - Might overflow after 922000000 s
# Monitor "Idle_Stats" (4 states)
# 5 saniye boyunca C-state ve frekans istatistiklerini göster
cpupower monitor -m Mperf,Idle_Stats sleep 5
# || Mperf || Idle_Stats
# PKG |CORE|CPU || C0 | Cx | Freq ||POLL | C1 | C2
# 0 | 0 | 0 || 2.3 | 97.7 | 1024 || 0 | 1.2 | 96.5
# powertop entegrasyonu
powertop --auto-tune # mevcut tüm güç tasarruf özelliklerini etkinleştir
powertop --csv=report.csv --time=60 # 60s raporla
cpupower monitor çıktısında C0 CPU'nun aktif olduğu zaman yüzdesi, Cx ise uyku halinde geçirdiği süredir. İyi optimize edilmiş gömülü bir sistemde boşta C0 < %5 olmalıdır.
07 Kernel config ve Device Tree
cpufreq için doğru kernel konfigürasyonu platform bağımlıdır. Genellikle bir cpufreq driver, bir veya birden fazla governor ve clock/regulator bağlantıları gerekir.
Temel kernel config seçenekleri
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_STAT=y # sysfs istatistik dosyaları
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y # önerilir
CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y
# Platform driver (ARM/DT tabanlı)
CONFIG_CPUFREQ_DT=y # generic DT-based driver
CONFIG_CPUFREQ_DT_PLATDEV=y
# ARM big.LITTLE
CONFIG_ARM_BIG_LITTLE_CPUFREQ=y
# Energy Model
CONFIG_ENERGY_MODEL=y
Platform driver ile clock ve regulator bağlantısı
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu0: cpu@0 {
device_type = "cpu";
compatible = "arm,cortex-a53";
reg = <0>;
enable-method = "psci";
operating-points-v2 = <&cpu_opp_table>;
clocks = <&ccu CLK_CPU>; /* clock provider */
clock-names = "cpu";
cpu-supply = <®_vdd_cpu>; /* regulator consumer */
#cooling-cells = <2>; /* thermal cooling */
};
};
/* PMIC regulator tanımı */
&axp209 {
regulators {
reg_vdd_cpu: dcdc2 {
regulator-name = "vdd-cpu";
regulator-min-microvolt = <700000>;
regulator-max-microvolt = <1300000>;
regulator-always-on;
};
};
};
DT tabanlı ARM SoC'lar için cpufreq-dt driver çoğunlukla yeterlidir. SoC'a özgü özellikler (örn. Rockchip pvtm, i.MX8 scaling) için platform-specific driver'lar gerekebilir — BSP kaynaklarını kontrol et.
08 Pratik: RPi4 thermal throttling · BeagleBone schedutil · INA219
Üç gerçek senaryo: Raspberry Pi 4'te termal kaynaklı throttling'i analiz etmek, BeagleBone Black'te schedutil governor ayarı yapmak ve INA219 ile gerçek güç tüketimini ölçmek.
1 — Raspberry Pi 4 Thermal Throttling İnceleme
# throttling durumunu oku (vcgencmd)
vcgencmd get_throttled
# throttled=0x0 → normal
# throttled=0x50000 → throttling oluştu (geçmişte)
# throttled=0x50005 → şu an throttling aktif!
# bit maskeleri:
# bit 0: under-voltage
# bit 1: arm freq capped
# bit 2: currently throttled
# bit 16-18: yukarıdakilerin geçmişte oluşup oluşmadığı
# sıcaklık ve frekansı aynı anda izle
while true; do
temp=$(vcgencmd measure_temp | cut -d= -f2)
freq=$(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq)
throttle=$(vcgencmd get_throttled)
echo "$(date +%T) | $temp | ${freq}kHz | $throttle"
sleep 1
done
# CPU'yu yükle ve throttling'i tetikle
stress-ng --cpu 4 --timeout 60s &
# throttling eşiği: RPi4 85°C üzerinde frekansı 1500→600 MHz'e düşürür
# soğutucu takarak veya frekansı sınırlayarak önle
echo 1200000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq
2 — BeagleBone Black schedutil ayarı
# mevcut governor ve OPP'leri gör
cpufreq-info
# available frequency steps: 300 MHz, 600 MHz, 720 MHz, 800 MHz, 1000 MHz
# schedutil'e geç (TPS65217 regulator otomatik voltaj ayarı yapar)
cpupower frequency-set -g schedutil
# schedutil rate_limit_us ayarı (gömülü için 4ms önerilir)
echo 4000 > /sys/devices/system/cpu/cpufreq/schedutil/rate_limit_us
# boşta ve yük altındaki frekansı karşılaştır
watch -n0.5 'cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq'
# systemd service ile kalıcı hale getir
cat /etc/systemd/system/cpufreq.service
[Unit]
Description=Set cpufreq governor
After=multi-user.target
[Service]
Type=oneshot
ExecStart=/usr/bin/cpupower frequency-set -g schedutil
ExecStart=/bin/sh -c 'echo 4000 > /sys/devices/system/cpu/cpufreq/schedutil/rate_limit_us'
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
3 — INA219 ile Gerçek Güç Tüketimi Ölçümü
#!/usr/bin/env python3
"""
INA219 I2C güç sensörü ile CPU governor karşılaştırması.
Devre: INA219 0.1Ω shunt, 0x40 adresi, I2C bus 1
Pip: pip3 install pi-ina219
"""
import time, subprocess
from ina219 import INA219, DeviceRangeError
SHUNT_OHMS = 0.1
ina = INA219(SHUNT_OHMS, address=0x40)
ina.configure()
def set_governor(gov):
subprocess.run(["cpupower", "frequency-set", "-g", gov],
capture_output=True)
time.sleep(0.5)
def measure(duration=10, label=""):
samples = []
t_end = time.time() + duration
while time.time() < t_end:
try:
power_mw = ina.power()
voltage = ina.voltage()
samples.append(power_mw)
except DeviceRangeError:
pass
time.sleep(0.1)
avg = sum(samples) / len(samples) if samples else 0
print(f"[{label:15s}] Ortalama güç: {avg:6.1f} mW "
f"(n={len(samples)})")
return avg
print("=== Governor Güç Karşılaştırması ===")
for gov in ["powersave", "schedutil", "ondemand", "performance"]:
set_governor(gov)
# boşta ölç
idle = measure(10, f"{gov}/idle")
# yük altında ölç
load = subprocess.Popen(["stress-ng", "--cpu", "1"])
time.sleep(1)
under = measure(10, f"{gov}/load")
load.terminate()
print(f" Tasarruf vs performance: {(1 - idle/under)*100:.1f}%")
print()
Tipik BeagleBone Black üzerinde: powersave boşta ~180 mW, performance yük altında ~750 mW. schedutil bu iki uç arasında dinamik kalır ve gereksiz yükte bile performans governor'ından ~%25 daha az güç tüketir.