 Autor: [Monika Wojciechowska](/autorzy/monika-wojciechowska) Specjalistka SEO i treści webowych · Zweryfikowano Kwiecień 2026

1.  [Strona główna](/) ›
2.  [Baza wiedzy](/baza-wiedzy/) ›
3.  perf — profilowanie CPU

# perf — profilowanie CPU i analiza wydajności na Linux

Opublikowano: 10 kwietnia 2026 · Kategoria: VPS

Serwer zjada 95% CPU, ale logi aplikacji wyglądają normalnie. Która funkcja powoduje bottleneck? Czy problem to brak danych w cache procesora, błędne przewidywanie skoków warunkowych, czy może wolne I/O? `perf` — narzędzie z jądra Linux — odpowiada na te pytania korzystając z hardware performance counters procesora, bez potrzeby modyfikacji kodu. Google i Netflix używają go codziennie do optymalizacji produkcyjnych systemów.

## Instalacja i perf stat — szybki przegląd wydajności

\# Ubuntu/Debian — zainstaluj linux-tools pasujące do kernela
sudo apt install linux-tools-$(uname -r) linux-tools-common -y
perf --version

# perf stat — podstawowe statystyki CPU
perf stat ls /usr

# Output:
# Performance counter stats for 'ls /usr':
#
#          1.234567      task-clock (msec)       # 0.456 CPUs utilized
#                 2      context-switches         # 0.001 M/sec
#                 0      cpu-migrations           # 0.000 M/sec
#               123      page-faults              # 0.100 M/sec
#         3,456,789      cycles                   # 2.800 GHz
#         2,890,123      instructions             # 0.84 insns per cycle  <--- IPC!
#           567,890      branches                 # 460.238 M/sec
#            23,456      branch-misses            # 4.13% of all branches
#

# Statystyki dla działającego procesu (-p PID)
perf stat -p $(pgrep php-fpm | head -1) sleep 10

# Własny zestaw liczników
perf stat -e cycles,instructions,cache-misses,cache-references,LLC-loads,LLC-load-misses \\
  python3 benchmark.py

## perf top — interaktywny profiler w czasie rzeczywistym

`perf top` działa jak htop ale na poziomie funkcji — pokazuje które funkcje w całym systemie lub konkretnym procesie zużywają najwięcej cykli CPU. Odświeża się co kilka sekund.

\# Systemowy top funkcji (wymaga root)
sudo perf top

# Tylko dla konkretnego procesu
sudo perf top -p $(pgrep node | head -1)

# Przykładowy output:
# Samples: 4K of event 'cycles', 4000 Hz, Event count (approx.): 1234567890
#   Overhead  Shared Object     Symbol
#   --------  ----------------  -------------------------
#     45.32%  \[kernel\]          \[k\] schedule
#     23.18%  libc.so.6         \[.\] malloc
#     15.44%  myapp             \[.\] process\_request
#      8.12%  libssl.so.3       \[.\] AES\_encrypt
#      4.23%  \[kernel\]          \[k\] tcp\_sendmsg

# Przydatne klawisz w trybie interaktywnym:
# 'a' - annotate (pokaż asm z hot path)
# 's' - sort by overhead
# 'f' - filter by name
# 'z' - zero counters (reset)

## perf record i perf report — szczegółowa analiza

\# Nagraj próbki z call graph (stack traces)
sudo perf record -g -p $(pgrep nginx | head -1) -- sleep 30
# Wynikowy plik: perf.data

# Analizuj interaktywnie (TUI)
sudo perf report -g

# Analizuj bez interakcji (dump do stdout)
sudo perf report --stdio | head -100

# Nagrywaj konkretne zdarzenie (LLC misses)
sudo perf record -e LLC-load-misses:u -g -p <PID> -- sleep 15
sudo perf report -g fractal

# Nagrywaj cały system przez N sekund
sudo perf record -a -g -F 99 -- sleep 30
# -a = all CPUs, -F 99 = 99 Hz sampling (bezpieczne dla prod)

# Nagrywaj tylko user-space (bez kernel frames)
sudo perf record -u -g ./myapp

## FlameGraph — wizualizacja wyników

Raporty tekstowe perf są trudne do analizy przy głębokich call graphs. FlameGraph Brendana Gregga zamienia je w interaktywne wykresy SVG — szerokie kolumny to gorące ścieżki kodu.

\# Pobierz FlameGraph scripts
git clone https://github.com/brendangregg/FlameGraph.git /opt/flamegraph

# Nagraj dane z call graph
sudo perf record -a -g -F 99 -- sleep 30

# Generuj FlameGraph SVG
sudo perf script | \\
  /opt/flamegraph/stackcollapse-perf.pl | \\
  /opt/flamegraph/flamegraph.pl > flamegraph.svg

# Otwórz w przeglądarce (lub pobierz przez scp)
python3 -m http.server 8888  # i wejdź na http://server-ip:8888/flamegraph.svg

# Filtruj tylko określone symbole
sudo perf script | \\
  /opt/flamegraph/stackcollapse-perf.pl | \\
  grep -v "^kernel" | \\
  /opt/flamegraph/flamegraph.pl \\
  --title "PHP-FPM CPU Profile" \\
  --width 1400 > php-profile.svg

# Różnicowy FlameGraph (before vs after optymalizacji)
# 1. Nagraj before.data i after.data
# 2. perf script -i before.data | stackcollapse-perf.pl > before.txt
# 3. perf script -i after.data  | stackcollapse-perf.pl > after.txt
# 4. difffolded.pl before.txt after.txt | flamegraph.pl > diff.svg

## Hardware counters — LLC misses i branch mispredictions

Counter

Dobra wartość

Problem gdy

Przyczyna / naprawa

IPC (insns/cycle)

\> 2.0

< 1.0

Cache misses, branch mispredictions, memory-bound app

LLC-load-misses

< 1% LLC-loads

\> 5%

Zła lokalność danych — przepisz struktury danych (SoA zamiast AoS)

branch-misses

< 1%

\> 3%

Unpredictable branches — sortuj dane przed pętlą, użyj branchless patterns

cache-misses

< 0.1%

\> 1%

Brak lokalności L1/L2 — prefetching, zmiana algorytmu

context-switches

Niskie

Tysiące/sek

Za dużo wątków względem CPU, spinlocki, I/O bound threads

## Profilowanie PHP-FPM i Node.js

\# PHP-FPM — wymaga PHP skompilowanego z --enable-frame-pointers
# Sprawdź czy jest wsparcie:
php -i | grep "frame pointers"
# lub sprawdź: readelf -s /usr/lib/php/... | grep frame

# Nagraj próbki dla master PHP-FPM
sudo perf record -g -F 99 -p $(pgrep -x php-fpm8.2 | head -1) -- sleep 30
sudo perf report --stdio | head -50

# Node.js — z mapowaniem JIT symbols
node --perf-basic-prof app.js &
NODE\_PID=$!

sudo perf record -g -F 99 -p $NODE\_PID -- sleep 30

# Zmerguj Node JIT map z perf symbols
sudo perf script --symfs /tmp | \\
  /opt/flamegraph/stackcollapse-perf.pl | \\
  /opt/flamegraph/flamegraph.pl > node-flame.svg

# Java — użyj async-profiler (nie wymaga frame pointers)
# wget https://github.com/async-profiler/async-profiler/releases/...
java -agentpath:/opt/async-profiler/lib/libasyncProfiler.so=start,event=cpu,file=profile.html app.jar

## Porównanie narzędzi profilowania

Narzędzie

Metoda

Narzut

Kiedy używać

perf

Sampling (PMU)

Niski (1-3%)

Produkcja, CPU profiling, cache analysis

gprof

Instrumentacja

Wysoki (20-50%)

Dev/test, wymaga recompile z -pg

Valgrind Callgrind

Simulacja CPU

Bardzo wysoki (10-50x)

Dokładny cache analysis, tylko dev/test

async-profiler

Sampling JVMTI

Niski

Java/Kotlin produkcja, bez safepoint bias

Py-Spy

Sampling Python

Minimalny

Python produkcja, FlameGraph output

rbspy

Sampling Ruby

Minimalny

Ruby on Rails produkcja

## Najczęstsze pytania

Czym jest perf i do czego służy? +

perf to narzędzie profilowania wydajności wbudowane w jądro Linux (linux-tools). Pozwala zbierać dane z hardware performance counters procesora (IPC, LLC misses, branch mispredictions), śledzić wywołania systemowe (perf trace), profilować CPU sampling (perf record + perf report) i analizować gorące punkty kodu. Używane przez Google, Meta i Netflix do optymalizacji produkcyjnych systemów.

Co to jest FlameGraph i jak go wygenerować? +

FlameGraph to wizualizacja stosu wywołań jako flame chart — szerokie prostokąty to funkcje zajmujące dużo CPU. Twórcą jest Brendan Gregg (brendangregg.com/FlameGraphs). Generuje się go: (1) perf record -g ./myapp, (2) perf script | stackcollapse-perf.pl | flamegraph.pl > out.svg. Wynikowy SVG jest interaktywny — można klikać, przybliżać i szukać wzorców. Alternatywnie użyj speedscope.app (online) lub Hotspot GUI.

Jakie hardware counters warto monitorować? +

Kluczowe hardware performance counters: LLC-load-misses (Last Level Cache misses) — wskazują na problemy z cache locality danych; branch-misses — mispredictions powodują opróżnienie pipeline CPU; instructions i cycles — IPC (instructions per cycle) poniżej 1 to problem; cache-misses — ogólne miss rate pamięci podręcznej. Wysoki LLC-load-misses lub niski IPC to typowe przyczyny wąskich gardeł CPU w aplikacjach serwerowych.

Jak profilować PHP-FPM lub Node.js z perf? +

Dla PHP-FPM: kompiluj PHP z --enable-frame-pointers i użyj perf record -g -p $(pgrep php-fpm) -- sleep 30, potem perf report. Dla Node.js: uruchom z --perf-basic-prof (generuje /tmp/perf-NNN.map z mapowaniem symbolów), potem perf record -g node --perf-basic-prof app.js, perf report --symfs /tmp. Dla Java użyj async-profiler z narzędziem jvm-attach, który obsługuje JIT-compiled symbols. Bez frame pointers (domyślne w większości dystrybucji) uzyskasz niekompletne stosy.

## Sprawdź oferty pasujące do tego scenariusza

Poniżej masz szybkie przejścia do ofert i stron z kodami rabatowymi tam, gdzie są dostępne.

Contabo

VPS z szybkim procesorem i dostępem do hardware performance counters

VPS + CPU

[Aktywuj rabat →](/out/contabo)

#Reklama · link partnerski

[Zobacz kod rabatowy →](/kody-rabatowe/contabo)

ProSerwer.pl

Polski VPS z pełnym dostępem root — niezbędne do perf i profilowania

Root access

[Aktywuj rabat →](/out/proserwer-pl)

#Reklama · link partnerski

[Zobacz kod rabatowy →](/kody-rabatowe/proserwer)

Mikr.us

Budżetowy VPS do nauki profilowania i analizy wydajności

Dev/Learn

[Aktywuj rabat →](/out/mikrus)

#Reklama · link partnerski

[Zobacz kod rabatowy →](/kody-rabatowe/mikrus)

## Powiązane strony

-   [strace i ltrace — diagnostyka procesów Linux](/baza-wiedzy/strace-debugging-linux)
-   [bpftrace — dynamiczne śledzenie z eBPF](/baza-wiedzy/bpftrace-dynamiczne-sledzenie)
-   [Valgrind — wykrywanie wycieków pamięci](/baza-wiedzy/valgrind-memory-debugging)
-   [Wszystkie artykuły](/baza-wiedzy/)