Tracy Profiler - Real-Time Frame Profiler Cheatsheet
Tracy ist ein Real-Time, Nanosekunden-Auflösung Hybrid Frame und Sampling Profiler, weit verbreitet in Spielen und Low-Latency C++ und Rust. Du addierst Lightweight Zone Makros zu deinem Code und Tracy streamt Timing-Daten live zu einer Desktop UI, wo du jeden Frame sehen kannst, jede Zone, GPU Timings, Memory Allocations und Lock Contention, während das Programm läuft. Seine Kombination aus Manueller Instrumentation plus Automatischer Sampling gibt beide Präzise Semantische Zones und Unzugeordnete Hot Spots.
Installation
| Komponente | Wie |
|---|
| Server (UI) | Build profiler/ aus dem Repo oder Download ein Release |
| Client (Library) | Add TracyClient.cpp + Headers zu deinem Build |
| Rust | cargo add tracy-client (oder tracing-tracy) |
| Aktivieren | Compile mit TRACY_ENABLE definiert |
| Verifikation | Launch die UI; es wartet auf eine Client Connection |
Instrumentierung C++
#include "tracy/Tracy.hpp"
void update() {
ZoneScoped; // zone named after the function
physics();
}
void render() {
ZoneScopedN("Render Pass"); // explicit name
ZoneColor(0x00FF00);
draw();
}
int main() {
while (running) {
update();
render();
FrameMark; // marks a frame boundary
}
}
| Macro | Zweck |
|---|
ZoneScoped | Time die Enclosing Scope |
ZoneScopedN("name") | Named Zone |
ZoneText(str, len) | Attach Text zu einer Zone |
FrameMark | Delimit Frames |
TracyPlot("fps", v) | Plot einen Numerischen Wert über Zeit |
TracyMessage(...) | Log eine Nachricht in die Timeline |
TracyLockable(...) | Track ein Mutex’s Contention |
Instrumentierung Rust
use tracy_client::{Client, span};
fn main() {
let _client = Client::start();
loop {
{
let _s = span!("update");
update();
}
tracy_client::frame_mark();
}
}
Oder wire es in tracing mit dem tracing-tracy Crate, so dass Existierende Spans in Tracy automatisch erscheinen.
Memory & GPU
| Feature | Wie |
|---|
| Allocation Tracking | TracyAlloc(ptr, size) / TracyFree(ptr) |
| Custom Allocators | Wrap Alloc/Free mit den Makros |
| GPU Zones (Vulkan/D3D/OpenGL) | TracyVkZone, TracyD3D12Zone, etc. |
| GPU Context | Create Einmal, dann Zones Attach zu es |
Die UI
| View | Zeigt |
|---|
| Timeline | Zones Pro Thread, Frame für Frame |
| Statistics | Aggregate Zeit Pro Zone |
| Find Zone | Histogram von einer Zone’s Durations |
| Compare | Diff Zwei Captures (Vorher/Nachher eine Änderung) |
| Memory | Allocation Timeline und Leaks |
| Locks | Contention zwischen Threads |
| Flame Graph | Aggregated Call Structure |
Workflow: Chasing ein Frame Spike
| Step | Action |
|---|
| 1 | Run mit dem Client Connected; Reproduce den Hitch |
| 2 | Finde den Langen Frame in der Timeline |
| 3 | Zoom In — Welche Zone Dominiert? |
| 4 | Öffne “Find Zone” für Jene Zone → Duration Histogram |
| 5 | Check des Outlier’s Kontext (Locks, Allocations, GPU Wait) |
| 6 | Fix, Capture Again, Nutze Compare zu Prove das Improvement |
Das Compare-Two-Captures-Workflow ist eines der Most praktischen Features von Tracy — es verwandelt “Feels Faster” in ein Gemessenes Delta.
Sampling Mode
Beyond Manuellen Zones, Tracy kann Call Stacks automatisch Samplen (Linux/Windows), Catching Zeit in Code, den du nicht instrumentiert hast. Combine Beide: Zones geben Semantische Struktur, Sampling füllt die Gaps.
Tracy vs Verwandte Profiler
| Aspekt | Tracy | Perf | Perfetto |
|---|
| Model | Instrumented Zones + Sampling | Sampling | System-Wide Tracing |
| Resolution | Nanosekunden | Sample Interval | Event-Level |
| Live View | Ja (Real-Time) | Nein | Post-Hoc |
| GPU Support | Built-in | Nein | Partial |
| Am besten für | Spiele, Frame-Based, Low-Latency C++/Rust | CPU Hot Paths | Whole-System Timelines |
Complements Perf und Perfetto; Tracy’s Edge ist Live, Frame-Orientiert, Instrumented Profiling.
Ressourcen