-
Notifications
You must be signed in to change notification settings - Fork 1
Performance Profiling Guide
This page explains how to use SparkEngine's built-in profiling tools to identify and resolve performance bottlenecks.
Source: SparkEngine/Source/Utils/Profiler.h, ChromeTracing.h, MemoryDebugger.h, DebugOverlay.h, FrameInspector.h
Enable the profiler overlay in-game:
auto& profiler = Profiler::GetInstance();
profiler.SetOverlayEnabled(true);Or via the debug console:
profiler.overlay on
profiler.gpu on
Every profiling sample is tagged with a category:
| Category | What it covers |
|---|---|
Frame |
Overall frame timing |
Render |
Draw calls, state changes |
Physics |
Jolt Physics simulation step |
Audio |
XAudio2 processing |
GameLogic |
ECS systems, gameplay |
Input |
Input polling and dispatch |
Particles |
Particle system updates |
UI |
ImGui layout and rendering |
Custom |
User-defined sections |
auto& profiler = Profiler::GetInstance();
// Begin/end a named section
profiler.BeginSection("PhysicsStep", ProfileCategory::Physics);
physicsSystem.Update(dt);
profiler.EndSection("PhysicsStep");{
PROFILE_SCOPE("RenderShadows", ProfileCategory::Render);
RenderShadowMaps();
} // Automatically ends when scope exitsfloat physicsMs = profiler.GetSectionTime("PhysicsStep");
float frameMs = profiler.GetFrameTime();
float fps = 1000.0f / frameMs;
// Get all section timings
auto sections = profiler.GetAllSections();
for (const auto& [name, timing] : sections) {
// timing.lastMs, timing.avgMs, timing.maxMs, timing.category
}GPU timing uses D3D11 timestamp queries (Windows only):
profiler.SetGPUProfilingEnabled(true);
// In rendering code
profiler.BeginGPUSection("ShadowPass");
RenderShadowMaps();
profiler.EndGPUSection("ShadowPass");
// Read results (available next frame due to GPU latency)
float shadowMs = profiler.GetGPUSectionTime("ShadowPass");The profiler maintains a rolling history of frame times:
// Get the last N frame times
auto history = profiler.GetFrameTimeHistory(); // vector<float>
// Get statistics
float avgFrame = profiler.GetAverageFrameTime(); // ms
float minFrame = profiler.GetMinFrameTime();
float maxFrame = profiler.GetMaxFrameTime();
float p99Frame = profiler.GetPercentileFrameTime(99);Export profiling data to Chrome's chrome://tracing format for detailed timeline analysis:
Source: SparkEngine/Source/Utils/ChromeTracing.h
ChromeTracing tracer;
// Record events
tracer.BeginEvent("Update", "GameLogic");
// ... work ...
tracer.EndEvent("Update", "GameLogic");
// Export to file
tracer.ExportToFile("profile_capture.json");Open the exported .json file in:
- Chrome: Navigate to
chrome://tracingand load the file - Perfetto UI: Drag and drop the file
- Start capture:
profiler.capture start - Play through the problematic scenario
- Stop capture:
profiler.capture stop - File is saved to
profile_capture.jsonin the working directory
Source: SparkEngine/Source/Utils/MemoryDebugger.h
auto stats = MemoryDebugger::GetInstance().GetCategoryStats();
for (const auto& cat : stats) {
// cat.name: "Physics", "Rendering", "Audio", etc.
// cat.currentBytes: currently allocated
// cat.peakBytes: high-water mark
// cat.totalAllocations: lifetime count
}Find the code locations that allocate most frequently:
auto hotspots = MemoryDebugger::GetInstance().GetHotSpots(10);
for (const auto& spot : hotspots) {
// spot.location: "Physics/RigidBody.cpp:42"
// spot.count: number of allocations from this site
// spot.totalBytes: total bytes allocated
}At shutdown:
SPARK_PRINT_LEAK_REPORT();
// Output:
// [LEAK] 0x7fff1234: 256 bytes (Physics) at PhysicsBody.cpp:87
// [LEAK] 0x7fff5678: 1024 bytes (Rendering) at Mesh.cpp:142The debug overlay renders real-time statistics as an ImGui window:
DebugOverlay::GetInstance().SetEnabled(true);| Section | Metrics |
|---|---|
| Frame | FPS, frame time (ms), min/max/avg |
| CPU | Per-category breakdown bar chart |
| GPU | Per-pass timing (shadow, geometry, post-process) |
| Memory | Total allocated, per-category breakdown |
| Draw Calls | Total draws, triangles, state changes |
| Physics | Active bodies, collision pairs, simulation time |
All profiling tools are accessible via the debug console:
| Command | Description |
|---|---|
profiler.overlay on/off |
Toggle the profiler overlay |
profiler.gpu on/off |
Toggle GPU timing queries |
profiler.capture start |
Begin Chrome Tracing capture |
profiler.capture stop |
End capture and save to file |
profiler.memory |
Print memory category summary |
profiler.leaks |
Print leak report |
profiler.hotspots [N] |
Show top N allocation hotspots |
profiler.reset |
Clear accumulated statistics |
- Check the CPU category breakdown — which system dominates?
- If
Renderis high: check draw call count, reduce overdraw, enable frustum culling - If
Physicsis high: reduce active body count, increase fixed timestep, simplify collision shapes - If
GameLogicis high: profile individual ECS systems, check for O(n^2) algorithms
- Enable GPU profiling:
profiler.gpu on - Check which pass is slowest (shadow, geometry, post-process)
- Reduce resolution, disable expensive effects (SSAO, bloom), lower shadow quality
- Run
profiler.memoryperiodically to track category growth - Check
profiler.hotspots 20for excessive allocation sites - Consider object pooling for frequently allocated types
- Run
profiler.leaksat shutdown to catch leaks
- Start a Chrome Tracing capture around the spike
- Look for single-frame anomalies: GC pauses, asset loads, physics explosions
- Use async loading for assets, spread heavy work across frames
SparkEngine's D3D11 renderer is compatible with RenderDoc for GPU debugging:
- Launch the engine through RenderDoc
- Press F12 (default) to capture a frame
- Inspect draw calls, shader state, and GPU resources
For detailed CPU profiling on Windows:
- Open the solution in Visual Studio
- Debug > Performance Profiler > CPU Usage
- Run the scenario and analyze the call tree
For memory analysis on Linux:
valgrind --leak-check=full --track-origins=yes ./bin/SparkEngine- Profile before optimizing. Measure first, then fix the actual bottleneck.
- Use Release builds for profiling. Debug builds have different performance characteristics.
- Profile representative scenarios. Test with real game content, not empty scenes.
- Track frame time, not FPS. Frame time is linear and easier to reason about.
- Watch for spikes, not just averages. A 1% spike can cause visible stuttering.
- Use Chrome Tracing for complex issues. The timeline view reveals ordering and overlap.
See Profiler and Debugging for the full API reference.
Published from 936a8401bf15. Edit the canonical source in wiki/.
- Documentation
- Docs route
- Wiki index
- Guides
- Tutorials
- Samples
- Examples
- API Reference
- API route
- Reference
- Build Guide
- Dependencies
- FAQ
- Changelog
- Roadmap
- Contributing
- Code of Conduct
- Home
- FAQ
- Getting Started
- Quick-Start Tutorial
- Making Your First Game
- Making Your First Multiplayer Game
- Artist Workflow Guide
- Editor Walkthrough
- Migration Guide
- How SparkEngine Works
- Architecture Overview
- Engine Architecture Flowchart
- Creating a Game Module
- Game Modules (catalog)
- Entity Component System
- Rendering and Graphics
- Physics
- Cloth Simulation
- Audio
- Input System
- Camera System
- Scripting with AngelScript
- Visual Scripting
- AI and Navigation
- Animation
- 2D Systems
- Networking
- Dedicated Server
- Multiplayer Quick Start
- Area Server Architecture
- Scene Management
- Large World Support
- Collaborative Editing
- Coroutine System
- Event System
- Event Response System
- Job System
- UI System
- UI Layout Extensions
- Localization
- Dialogue System
- Destruction System
- Replay System
- Achievement System
- Loading System
- Mod System
- Content Delivery
- Tween System
- Memory Integrity
- Gameplay Systems
- Terrain and Procedural Generation
- Save System
- Persistence System
- Day Night Cycle and Weather
- Cinematic Sequencer
- Runtime Prefabs
- SparkEditor
- Editor Tutorials
- SparkConsole
- SparkDaemon
- Shader Pipeline
- Asset Pipeline
- Asset Validation
- Asset Migration
- Game Packaging
- Online Services
- DataTable System
- Loot and Crafting System
- CSG System
- Font System
- Timer Manager
- Movie Render Pipeline
- HLOD and World Partition
- Remote Debug System
- Selection Manager
- Asset Dependency Graph
- Editor Automation
- File Watcher
- Project Templates
- System Requirements
- VR Support
- Mobile Platform
- Accessibility
- Platform Input
- Cross-Compilation: Wine Testing
- RHI Abstraction Layer
- D3D11 Backend
- D3D12 Backend
- Vulkan Backend
- OpenGL Backend
- Metal Backend
- DXR Raytracing
- Hybrid Ray Tracing
- Upscaling (DLSS/FSR)
- Render Graph
- Shader Graph
- GPU Particles
- GPU-Driven Rendering
- Volumetric Fog
- Volumetric Clouds
- Global Illumination
- Virtual Texturing
- Water Rendering
- Clustered Lighting
- Material System
- Post-Processing
- Shadow System
- Particle System
- Decal System
- Sky and Atmosphere
- Foliage System
- Mesh Shaders
- Neural Rendering
- Configuration Reference
- Performance Tips
- Benchmark Framework
- Threading Model
- Memory Safety
- Memory Management Patterns
- Build System and CMake Modules
- Profiler and Debugging
- Performance Profiling Guide
- Telemetry System
- Golden Image Testing
- Utilities
- Testing
- Codebase Statistics
- Codebase Health
- Error Handling Patterns
- Hot Reload Overview
- Troubleshooting
- Contributing
- Workflow Patterns
- Build Optimizations
- CI Reproducible Builds
- GitHub API and PR Checks
- Git Rebase Conflicts
- Clang-Format
- Code Quality Violations
- AI Bloat Pattern
- MinGW + Wine Cross-Compilation
- Live Editor Testing
- Engine & Renderer Landscape
- DuetOS Portability Catalog
- Five-Engine Analysis
- Eleven-Engine Analysis
- ThorVG / Unity Graphics Analysis
- Advanced Techniques Catalog
- Third-Party Library Evaluation
- Engine Viability Evaluation
- Engine Feature Recommendations
- Project Recommendations
- Mac Compatibility Analysis
- Codebase Observations
- Codebase Bloat Audit
- Test Suite Audit
- Documentation Coverage Audit
- ThirdParty Dependencies Audit
- Load Test Baseline
- Gameplay Systems Status
- SparkGame Module Status
- Stub and Abandoned Features
- Memory Integrity System
- Memory Safety Evaluation
- Hardware Acceleration Systems
- Jolt Physics Integration
- GPU/CPU Separation Plan
- Daemon Services Architecture
- Reflection & Polymorphism Refactoring Plan
- SparkBuild In-Tree
- Wine No-JobSystem Breakthrough
- Wine Role and Fallback Tiers