00 RT latency nedir? — jitter ve WCET kavramları
Real-time sistemlerde performans ölçütü ortalama süre değil, en kötü durum gecikme süresi (WCET — Worst-Case Execution Time) ve bunun öngörülebilirliğidir.
Latency, jitter ve WCET
Latency (gecikme), bir olayın gerçekleşmesi ile sistemin bu olaya yanıt vermesi arasındaki süredir. Örneğin: interrupt gelir, interrupt handler çalışır — aradaki geçen süre interrupt latency'dir.
Jitter, ardışık latency ölçümleri arasındaki varyasyondur. Latency'nin 47 µs ve 48 µs arasında dalgalanması düşük jitter anlamına gelir; 10 µs ile 200 µs arasında değişmesi yüksek jitter demektir. Hard RT sistemlerde düşük jitter, düşük ortalama kadar önemlidir.
WCET, uzun süre boyunca gözlemlenen maksimum latency değeridir. "1 milyon ölçümde hiçbiri 50 µs'yi geçmedi" ifadesi, o sistemin WCET'inin (ölçüm süresince) 50 µs olduğunu anlatır. Standart Linux'ta WCET tahmin edilemez; PREEMPT_RT ile kernel preemption engelleri kaldırılarak WCET düşürülür ve öngörülebilir hale getirilir.
| Kernel yapısı | Tipik ortalama latency | Tipik WCET | Öngörülebilirlik |
|---|---|---|---|
| PREEMPT_NONE | ~5 µs | onlarca ms | Düşük |
| PREEMPT (desktop) | ~2 µs | ~1 ms | Orta |
| PREEMPT_RT | ~5 µs | <50 µs (iyi tuning) | Yüksek |
| RTOS (FreeRTOS) | <1 µs | <10 µs | Çok yüksek |
Latency kaynakları
Linux'ta latency'ye katkıda bulunan başlıca faktörler şunlardır: non-preemptible kod bölgeleri (spinlock, RCU critical section), yüksek frekanslı timer interrupt'ları, NUMA ve cache miss'ler, SMI (System Management Interrupts) — bu son öge BIOS düzeyinde oluşur ve yazılımdan tamamen gizlenebilir, dolayısıyla en tehlikeli latency kaynağıdır.
SMI (System Management Interrupt), BIOS/UEFI firmware tarafından üretilir ve işlemciyi SMM (System Management Mode) moduna alır. Bu süre zarfında hiçbir OS kodu çalışmaz. Bazı BIOS implementasyonlarında SMI her saniye onlarca kez tetiklenebilir. hwlatdetect ile SMI kaynaklı latency spike'ları tespit edilebilir.
01 rt-tests paketi — araç ailesi
rt-tests, PREEMPT_RT çekirdeklerini doğrulamak için geliştirilmiş, birbirini tamamlayan araçlardan oluşan bir pakettir.
Kurulum
# Debian/Ubuntu paket deposundan
apt-get install rt-tests
# Kaynak koddan derleme (önerilen — güncel sürüm için)
git clone https://git.kernel.org/pub/scm/utils/rt-tests/rt-tests.git
cd rt-tests
make
sudo make install
Araç ailesi
| Araç | Amaç | Tipik kullanım |
|---|---|---|
| cyclictest | Timer latency ölçümü | RT kernel doğrulama, tuning |
| hackbench | Scheduler yük üretici | Cyclictest ile birlikte yük oluşturma |
| pi_stress | Priority inheritance testi | RT mutex priority inversion kontrolü |
| hwlatdetect | SMI / hardware latency tespiti | BIOS SMI spike analizi |
| oslat | OS jitter ölçümü | Userspace scheduling jitter |
| ssdd | Signal/syscall latency | Signal delivery süresi ölçümü |
hwlatdetect ile SMI tespiti
# hwlatdetect 10 saniye boyunca polling yapar
# Kernel SMI sırasında döngüde boşluk görür
hwlatdetect --duration=30 --threshold=10
# Çıktı örneği:
# hwlatdetect: version 1.0
# parameters:
# Latency threshold: 10us
# Sample window: 1000000us
# Sample width: 500000us
# Non-sampling period: 500000us
# Output File: None
# Starting detection...
# Max latency: 23us (SMI kaynaklı spike!)
02 cyclictest parametreleri — kapsamlı referans
cyclictest, periyodik timer'lar oluşturarak beklenen uyku süresi ile gerçek uyku süresinin farkını ölçer. Bu fark, sistemin latency değerini verir.
Temel çalışma prensibi
Thread başlar, t0 = şimdiki zaman
│
▼
clock_nanosleep(t0 + interval) ile uyur
│
▼
Uyanır, t1 = şimdiki zaman
│
Latency = t1 - (t0 + interval)
│
▼
Sonraki döngüye geç, tekrar et
Önemli parametreler
-t $(nproc) tüm çekirdekleri test eder.-p 99.-h 400 → 0-400 µs arası dağılım.-l 0 sonsuz çalıştırır. Belirli test süresi için -D kullanılabilir.-D 60s, -D 10m, -D 24h.-a 2-3 thread'leri CPU 2 ve 3'e bağlar.Tipik kullanım senaryoları
# Hızlı doğrulama (1 thread, 100k döngü)
cyclictest -p 99 -t 1 -l 100000
# Tam RT doğrulama (tüm çekirdekler, 1M döngü, histogram)
cyclictest -p 99 -t $(nproc) -l 1000000 -h 400 -q
# 24 saatlik dayanıklılık testi
cyclictest -p 99 -t $(nproc) -D 24h -h 400 --json=/tmp/results.json
# CPU isolation ile belirli çekirdek
cyclictest -p 99 -t 2 -a 2,3 -i 200 -D 60m -h 400
# SMI tespiti ile (x86)
cyclictest -p 99 -t $(nproc) -D 60s -h 400 --smi
03 Latency histogramı çizimi
Histogram çıktısı, latency dağılımının görsel analizi için en değerli araçtır. Tek bir maksimum değerin ötesinde, tüm dağılımı görmek gerekir.
Histogram verisi üretimi
# Histogram verisi üret (4 thread, 10 dakika)
cyclictest -p 99 -t 4 -a 2,3,4,5 -D 10m \
-h 400 --histfile=/tmp/hist.dat -q
# Dosya formatı:
# #Histogram
# #Index Thread0 Thread1 Thread2 Thread3
# 1 0 0 0 0
# 2 12 8 15 6
# 3 45238 41120 43001 40987
# ...
# Overflows: 0 0 0 0
gnuplot ile görselleştirme
#!/bin/bash
# hist-plot.sh — Histogram grafiği oluştur
cat > /tmp/hist.gnuplot << 'EOF'
set terminal png size 1200,600 font "monospace,11"
set output "/tmp/latency-histogram.png"
set title "RT Latency Histogram — cyclictest"
set xlabel "Latency (µs)"
set ylabel "Occurrences"
set logscale y
set xrange [0:100]
set yrange [1:*]
set grid
set key top right
plot "/tmp/hist.dat" using 1:2 with impulses lc "blue" title "CPU2", \
"/tmp/hist.dat" using 1:3 with impulses lc "red" title "CPU3", \
"/tmp/hist.dat" using 1:4 with impulses lc "green" title "CPU4", \
"/tmp/hist.dat" using 1:5 with impulses lc "orange" title "CPU5"
EOF
gnuplot /tmp/hist.gnuplot
echo "Grafik: /tmp/latency-histogram.png"
JSON çıktısından analiz
cyclictest -p 99 -t $(nproc) -D 60s \
--json=/tmp/ct-results.json -q
# Maksimum ve ortalama latency
jq '.thread[] | {cpu: .id, max: .max, avg: .avg, min: .min}' \
/tmp/ct-results.json
# Tüm thread'lerin global maksimumu
jq '[.thread[].max] | max' /tmp/ct-results.json
# 50 µs eşiğini geçen toplam ölçüm sayısı (histogram üzerinden)
jq '[.histogram.thread[].histogram | to_entries[]
| select(.key | tonumber >= 50) | .value] | add // 0' \
/tmp/ct-results.json
Histogramı okuma rehberi
İdeal bir PREEMPT_RT histogramı şu özelliklere sahip olmalıdır: büyük çoğunluk (>%99.9) 20-30 µs bandında yoğunlaşır, kuyruk kısmen 50 µs'e kadar uzanabilir, 100 µs üzerinde hiç ölçüm olmamalıdır. "Long tail" denen uzun kuyruk varlığı, tutarsız bir kaynağa işaret eder — genellikle SMI, NUMA erişimi veya kötü ayarlanmış IRQ affinity.
04 /proc/sys/kernel tunables
Kernel'in çalışma zamanında ayarlanabilen bazı parametreleri, RT latency üzerinde doğrudan etkiye sahiptir. Bu tunables sysctl veya doğrudan procfs üzerinden ayarlanabilir.
Kritik tunables
# RT throttling'i kapat (kritik!)
sysctl -w kernel.sched_rt_runtime_us=-1
# NUMA dengelemeyi kapat
sysctl -w kernel.numa_balancing=0
# Timer migrasyonunu kapat
sysctl -w kernel.timer_migration=0
# Transparent HugePages kapat (TLB shootdown latency)
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
# Kalıcı ayar için /etc/sysctl.d/99-rt.conf:
cat > /etc/sysctl.d/99-rt.conf << 'EOF'
kernel.sched_rt_runtime_us = -1
kernel.numa_balancing = 0
kernel.timer_migration = 0
EOF
sysctl --system
CPU frequency scaling
# Tüm CPU'lar için performance governor
for cpu in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do
echo performance > $cpu
done
# P-state ve turbo kontrolü (Intel)
echo 1 > /sys/devices/system/cpu/intel_pstate/no_turbo
# cpupower kullanarak (rt-tests paketinde bulunur)
cpupower frequency-set -g performance
05 IRQ affinity ve CPU isolation
RT task'ların çalıştığı CPU çekirdeklerini sistem kesmelerinden izole etmek, en etkili latency azaltma tekniklerinden biridir.
Kernel boot parametreleri
# CPU 2 ve 3'ü izole et:
# isolcpus= → Bu CPU'ları scheduler'dan çıkar
# rcu_nocbs= → RCU callback'lerini bu CPU'lardan taşı
# nohz_full= → Tick'siz mod (1 Hz'den az interrupt)
# kthread_cpus → Kernel thread'lerini bu CPU'lardan uzak tut
GRUB_CMDLINE_LINUX="isolcpus=2,3 rcu_nocbs=2,3 nohz_full=2,3 \
kthread_cpus=0,1 irqaffinity=0,1 \
processor.max_cstate=1 idle=poll"
IRQ affinity ayarı
# irqbalance'ı durdur (otomatik IRQ dağıtımı RT'ye zararlı)
systemctl stop irqbalance
systemctl disable irqbalance
# Mevcut IRQ'ları listele
cat /proc/interrupts | head -20
# Belirli IRQ'yu CPU 0,1'e bağla (hexadecimal CPU mask)
# CPU 0 → mask 0x1, CPU 1 → mask 0x2, CPU 0+1 → mask 0x3
IRQ_NUM=24 # ör. ağ kartı IRQ'su
echo 3 > /proc/irq/${IRQ_NUM}/smp_affinity
# İnsan okunabilir liste formatı
echo 0,1 > /proc/irq/${IRQ_NUM}/smp_affinity_list
# Tüm IRQ'ları CPU 0,1'e toplu taşı
for irq in /proc/irq/*/smp_affinity_list; do
echo 0,1 > $irq 2>/dev/null || true
done
RT task'ı izole CPU'ya bağlama
# cyclictest'i izole CPU 2,3'te SCHED_FIFO prio 99 ile çalıştır
taskset -c 2,3 cyclictest -p 99 -t 2 -a 2,3 -D 60m -h 400
# Mevcut bir sürece CPU affinity ata
taskset -c 2,3 -p $PID
# SCHED_FIFO önceliği ata
chrt -f 80 -p $PID
# Doğrulama
grep Cpus_allowed_list /proc/$PID/status
chrt -p $PID
cgroup ile CPU izolasyonu
# RT görevler için özel cgroup oluştur
mkdir -p /sys/fs/cgroup/rt-tasks
# CPU partition olarak işaretle
echo isolated > /sys/fs/cgroup/rt-tasks/cpuset.cpus.partition
echo 2,3 > /sys/fs/cgroup/rt-tasks/cpuset.cpus
# RT görevini bu cgroup'a al
echo $PID > /sys/fs/cgroup/rt-tasks/cgroup.procs
06 stress-ng ile yük altında test
RT latency testleri yalnızca boşta değil, gerçekçi sistem yükü altında da yapılmalıdır. stress-ng, kontrollü yük senaryoları oluşturmak için idealdir.
stress-ng temel kullanımı
# CPU yükü (CPU 0,1 üzerinde — izole CPU'lara dokunma)
taskset -c 0,1 stress-ng --cpu 2 --timeout 60s &
# I/O yükü
taskset -c 0,1 stress-ng --io 4 --timeout 60s &
# VM yükü (bellek baskısı)
taskset -c 0,1 stress-ng --vm 2 --vm-bytes 512M --timeout 60s &
# Matrix (FPU yükü)
taskset -c 0,1 stress-ng --matrix 2 --timeout 60s &
# Kombinasyon: gerçekçi üretim benzeri yük
taskset -c 0,1 stress-ng \
--cpu 2 --io 2 --vm 1 --vm-bytes 256M \
--matrix 1 --timeout 300s &
STRESS_PID=$!
echo "Stress PID: $STRESS_PID"
Kombinasyon testi: cyclictest + stress-ng
#!/bin/bash
# rt-load-test.sh — Yük altında RT latency ölçümü
# 1. Ön hazırlık
sysctl -w kernel.sched_rt_runtime_us=-1
sysctl -w kernel.numa_balancing=0
for cpu in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do
echo performance > $cpu 2>/dev/null || true
done
# 2. Yük başlat (CPU 0,1 üzerinde)
taskset -c 0,1 stress-ng \
--cpu 2 --io 4 --vm 2 --vm-bytes 256M \
--timeout 660s &
STRESS_PID=$!
# 3. Yükün oturması için bekle
sleep 5
# 4. cyclictest çalıştır (CPU 2,3 — izole)
cyclictest -p 99 -t 2 -a 2,3 \
-D 600s -h 400 --json=/tmp/load-test.json -q
# 5. Stres'i durdur
kill $STRESS_PID 2>/dev/null
# 6. Sonuçları analiz et
echo "=== Yük altında RT Latency Sonuçları ==="
jq '.thread[] | "CPU\(.id): min=\(.min)µs avg=\(.avg)µs max=\(.max)µs"' \
/tmp/load-test.json -r
Beklenen latency artışı
| Senaryo | Boşta max latency | Yük altında max latency |
|---|---|---|
| CPU yükü (izole CPU'larda) | ~20 µs | ~25 µs (+%25) |
| CPU yükü (RT CPU'larda) | ~20 µs | ~200+ µs (kabul edilemez) |
| I/O yükü | ~20 µs | ~35 µs (+%75) |
| Bellek baskısı | ~20 µs | ~50 µs (TLB flush) |
Bu tablo, CPU izolasyonunun neden kritik olduğunu net biçimde ortaya koyar. RT CPU'larda yük çalıştırmak latency'yi on katına çıkarabilirken, doğru izolasyonla yük etkisi minimum düzeyde tutulabilir.
07 Pratik: <50 µs Industrial Linux Tuning
Endüstriyel bir kontrol sistemi için <50 µs WCET hedefine ulaşmanın adım adım süreci. BIOS/UEFI ayarlarından kernel derlemeye, cmdline'dan runtime tuning'e.
Adım 1: BIOS/UEFI ayarları
| BIOS Ayarı | Hedef değer | Neden |
|---|---|---|
| Hyper-Threading (SMT) | Disable | Sibling thread interference önler |
| CPU C-states | C0 only (disable C1+) | C-state exit latency'si ortadan kalkar |
| Turbo Boost | Disable | Frekans varyasyonu yok, öngörülebilir |
| NUMA interleaving | Disable | NUMA erişim sürprizleri önlenir |
| Legacy USB emulation | Disable | USB SMI kaynağı ortadan kalkar |
| Power management (ACPI) | High Performance | P-state geçişi latency'ye neden olmaz |
Adım 2: Kernel konfigürasyonu
CONFIG_PREEMPT_RT=y # Full preemption
CONFIG_HZ_1000=y # 1 kHz timer (1 ms granülarite)
CONFIG_NO_HZ_FULL=y # Tickless mode
CONFIG_RCU_NOCB_CPU=y # RCU callback offload
CONFIG_IRQ_FORCED_THREADING=y # Tüm IRQ'ları thread yap
# Enerji tasarrufu özelliklerini kapat
# CONFIG_CPU_IDLE is not set
# CONFIG_CPU_FREQ is not set (alternatif: cpufreq-fixed)
# NUMA ve memory compaction
CONFIG_COMPACTION=n # Bellek compaction latency'si önler
Adım 3: Kernel cmdline
GRUB_CMDLINE_LINUX="
isolcpus=2,3,4,5
rcu_nocbs=2,3,4,5
nohz_full=2,3,4,5
kthread_cpus=0,1
irqaffinity=0,1
processor.max_cstate=0
idle=poll
intel_idle.max_cstate=0
pcie_aspm=off
audit=0
nosoftlockup
skew_tick=1
"
Adım 4: Runtime tuning scripti
#!/bin/bash
# RT tuning — systemd servisi olarak boot'ta çalıştır
set -e
echo "[RT-TUNE] Kernel tunables ayarlanıyor..."
sysctl -w kernel.sched_rt_runtime_us=-1
sysctl -w kernel.numa_balancing=0
sysctl -w kernel.timer_migration=0
sysctl -w vm.swappiness=0
echo "[RT-TUNE] THP kapatılıyor..."
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
echo "[RT-TUNE] CPU governor: performance..."
for gov in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do
echo performance > $gov 2>/dev/null || true
done
echo "[RT-TUNE] irqbalance durduruluyor..."
systemctl stop irqbalance 2>/dev/null || true
echo "[RT-TUNE] IRQ affinity: CPU 0,1..."
for sma in /proc/irq/*/smp_affinity_list; do
echo 0,1 > $sma 2>/dev/null || true
done
echo "[RT-TUNE] Tamamlandı."
Adım 5: Doğrulama ve kabul kriteri
# 1 saatlik stres testi ile doğrulama
taskset -c 0,1 stress-ng --cpu 2 --io 4 --vm 2 \
--vm-bytes 256M --timeout 3660s &
sleep 30 # Yükün oturması için bekle
cyclictest -p 99 -t 4 -a 2,3,4,5 \
-D 3600s -h 400 --json=/tmp/rt-verify.json -q
# Kabul kriteri: max latency < 50 µs
MAX_US=$(jq '[.thread[].max] | max' /tmp/rt-verify.json)
echo "Global MAX latency: ${MAX_US} µs"
if [ "$MAX_US" -lt 50 ]; then
echo "PASS: < 50 µs hedefi karşılandı"
else
echo "FAIL: Hedef aşıldı — daha fazla tuning gerekiyor"
exit 1
fi
<50 µs hedefine ulaşmak mümkün olmadığında önce hwlatdetect ile SMI kaynaklı spike'lar kontrol edilmelidir. SMI latency'si donanım ve BIOS'a özgü olduğundan yazılım optimizasyonuyla çözülemez; farklı donanım tercih edilmesi gerekebilir.