Instruments: CPU profiles and engine markers
Process selection, repeatable recordings, call trees and measurement limits.
Use Instruments to measure process behavior on macOS. Start with Time Profiler to investigate CPU load. It samples stacks periodically: the result is a sample distribution, not exact timing for every call or a GPU measurement. See Apple's call tree guide.
Choose the process and build
Profile the editor for editor slowdowns and the game for game slowdowns. Embedded play, a separate game window and the editor can involve different processes: record the executable path and PID. For comparisons, keep the project, camera, renderer, resolution, VSync/FPS limit, input and configuration identical.
Build optimized native code with symbols from Source, alongside SConstruct:
scons platform=macos target=editor arch=arm64 dev_build=no optimize=speed_trace debug_symbols=yes -j4On Intel, use x86_64. This example excludes C#; follow the separate macOS managed-build stages for C#. Do not treat a slow debug configuration as a release-performance measurement. Optimization can merge or inline functions, so samples are not a complete inventory of calls.
debug_symbols=yes retains symbolization information. For separate symbols, add separate_debug_symbols=yes and keep the resulting .dSYM with its matching binary. For raw addresses, check symbols, UUIDs and architecture; a different .dSYM with the same version number 1.0.0 is insufficient.
Record a useful interval
- Open Instruments from Xcode and select Time Profiler. UI names and locations depend on the Xcode version.
- Select the actual executable or attach to the correct PID. Use
--editor --path /absolute/projectfor the editor and--path /absolute/projectfor the game. The path is the directory containingproject.reckfell. - Wait for imports, loading and shader warm-up when measuring steady gameplay. If startup is the problem, record it separately and state the cache condition.
- Record a short repeatable action, such as one camera pass along one route. Note its start and end, stop recording and select that timeline range.
- Inspect the relevant threads and call tree; save the
.trace, build configuration, inputs and action description. Repeat the same scenario after a change.
Interpret the results
| Observation | Next step |
|---|---|
| High total weight | Inspect child calls: inclusive weight includes them. Do not attribute all that time to the parent function body. |
| High self weight | Inspect the function's own work within the selected interval. |
| Waiting/VSync dominates | Check FPS limits, threads, CPU and GPU separately. A waiting stack does not prove that function performs heavy computation. |
| A short spike disappears in aggregate statistics | Select it on the timeline rather than averaging it with a long idle interval. |
| Hide System Libraries hides the cause | Restore libraries and inspect the entire stack; the filter hides rows, not work. |
A CPU profile does not rule out GPU bottlenecks, allocations, leaks or I/O delays. Use the relevant instruments and separate measurements. Sample counts are not exact call counts, and a function missing from a short recording may still have executed.
Engine markers
Ordinary Time Profiler sampling does not require profiler=instruments. That build flag enables Reckfell native signposts for instrumented regions; it supplements sampling rather than automatically tracing every C# method:
scons platform=macos target=editor arch=arm64 dev_build=no optimize=speed_trace debug_symbols=yes profiler=instruments -j4The current backend emits a Frame event and ReckfellProfileZone intervals; its script-zone and memory macros are empty. Add the appropriate signposts/Points of Interest instrument in your Instruments version to inspect markers. For missing markers, check the selected build, process, interval and recording settings first. Do not enable memory or on-demand profiler flags expecting them to configure Instruments: the build script reports those options as ignored by this backend. Configure call stack and memory profiling in Instruments; a build flag alone does not prove actual capture.
Build parameters and backend implementation were reviewed. No macOS, Instruments, .trace, native symbolization or CPU/GPU measurement was executed in this review; no numerical performance promises are made here.