|
| template<unsigned Capacity> |
| static void | install (Buffer< Capacity > &buffer) |
| | Claims root counter 2 and starts recording into the buffer.
|
| |
| static void | uninstall () |
| | Stops recording. Root counter 2 is left running.
|
| |
| static bool | installed () |
| |
| static uint32_t | now () |
| | Reads a timestamp, as stored in the buffer.
|
| |
| static uint32_t | elapsed (uint32_t start, uint32_t end) |
| | System clock cycles from timestamp start to timestamp end.
|
| |
| template<typename F > |
| static BenchResult | bench (const Zone &zone, unsigned count, F &&function) |
| | Runs function count times, timing each run.
|
| |
| template<typename F > |
| static void | forEach (F &&function) |
| | Calls function(zone, start, cycles, vsync, depth, stackDepth) for every entry still in the buffer, oldest first.
|
| |
| static bool | dumpPCDRV (const char *path) |
| | Writes every entry still in the buffer to a host file through PCDRV, one line each, oldest first: vsync, depth, stack depth, start timestamp in hex, cycles, zone name, file:line. Returns false if the file could not be created or a write fell short.
|
| |
Scoped profiler: timed scopes recorded into a ring buffer.
A PSYQO_PROFILE_SCOPE("name") statement times the rest of its enclosing block and records the zone, start, end, vsync count and nesting depth into a ring buffer when the block exits. Nothing is linked unless the program uses it, and nothing is recorded until a buffer is installed:
void Renderer::render() {
...
}
static void install(Buffer< Capacity > &buffer)
Claims root counter 2 and starts recording into the buffer.
Definition profiler.hh:108
#define PSYQO_PROFILE_SCOPE(name)
Profiles the rest of the enclosing block under name, a string literal.
Definition profiler.hh:267
Storage for the ring buffer, with room for Capacity scopes.
Definition profiler.hh:92
PCSX-Redux reads the buffer live and draws it as a timeline in its Scope Profiler window. On a console, forEach or dumpPCDRV gets the entries out.
Time comes from root counter 2, which install claims and sets to free-run on the system clock, combined with psyqo's hblank counter on root counter 1. Every time is in system clock cycles, exact for scopes up to about 4 seconds long. The layout of the buffer, and how the two counters combine, are in common/hardware/pcsxprof.h.
Scopes are meant for the main loop. The nesting depth is one global, so a scope inside an interrupt handler, or one held across a coroutine suspension while another scope runs, records the wrong depth. The times stay right. A scope costs about 160 cycles in PCSX-Redux's interpreter (about 60 to begin, 100 to end), almost all outside its own measured span but inside the span of any scope around it. So a short function reads about that much lower than a per-function profile of the same build, which also counts the scope itself.