Changes between Version 1 and Version 2 of EngineProfiling


Ignore:
Timestamp:
Jul 31, 2011, 11:16:18 PM (13 years ago)
Author:
Philip Taylor
Comment:

more profiling

Legend:

Unmodified
Added
Removed
Modified
  • EngineProfiling

    v1 v2  
    2828and it will measure all code from the `PROFILE` until the end of the current scope. (You can also use `PROFILE_START("foo"); ... PROFILE_END("foo");` which automatically add scoping braces.)
    2929
     30The profiler is relatively expensive; you usually shouldn't put `PROFILE` in code that will be called thousands of times per frame, since the profiling overhead will dominate the code you're trying to measure.
     31
    3032Pressing F11 multiple times will toggle through different profiler modes (script data, network data, renderer data).
    3133
    3234Pressing Shift+F11 will save `profile.txt` somewhere (usually the `binaries/system/` directory, assuming you're running code from SVN). Pressing it multiple times (without restarting the game) will append new measurements to that file.
     35
     36== Low-overhead timer ==
     37
     38A less fancy way to measure sections of code is:
     39{{{
     40#include "lib/timer.h"
     41...
     42{
     43  TIMER(L"description");
     44  ... code to measure ...
     45}
     46}}}
     47which will record the time from `TIMER` until the end of the current scope, then immediately print it via `debug_printf` (which goes to `stdout` on Unix, and the debugger Output window on Windows).
     48
     49To measure cumulative time spent in a section of code:
     50{{{
     51#include "lib/timer.h"
     52TIMER_ADD_CLIENT(tc_SomeDescription);
     53...
     54{
     55  TIMER_ACCRUE(tc_SomeDescription);
     56  ... code to measure ...
     57}
     58}}}
     59which will sum the time spent, then print it via `debug_printf` once when the game is shutting down. The output will be like
     60{{{
     61TIMER TOTALS (9 clients)
     62-----------------------------------------------------
     63  tc_SomeDescription: 10.265 Mc (12x)
     64  ...
     65}}}
     66saying the cumulative time, measured in CPU cycles (kc = kilocycles (10^3^), Mc = megacycles (10^6^), etc). (It measures cycles since that's cheaper and more reliable than converting to seconds, given that clock frequency can change while the game is running. Divide by your CPU frequency manually to get real time). This should have significantly lower overhead than `PROFILE`, so you can use it in functions that get called more often.
     67
     68== Simulation replay mode ==
     69
     70If you're not measuring graphics or GUI code, replay mode lets you run the simulation (the gameplay code and scripts and the AI etc) at maximum speed with all graphics disabled. This should be fully deterministic (i.e. you'll get the same results on each run) and doesn't need user interaction (so you can easily run in Valgrind).
     71
     72First, play the game normally, in either single-player or multiplayer. It will generate a file `~/.config/0ad/logs/sim_log/${PID}/commands.txt` (or somewhere in `%APPDATA%\logs\` on Windows) based on the process ID; looking for the newest directory should find it. This contains the map setup data and a list of all players' inputs, so the game can be replayed. You might want to copy the `commands.txt` to somewhere memorable.
     73
     74Run the game like
     75{{{
     76./pyrogenesis -replay=path/to/commands.txt
     77}}}
     78(or something equivalent on Windows). It will print its status to `stdout` (or the Output window on Windows). It gives the MD5 checksum of the complete simulation state once it's finished, which is handy if you're changing the code and want to make sure you're not affecting the simulation behaviour. Run in a profiler to measure whatever you want to measure.
     79
     80It also stores the in-game profiler state in `profile.txt` every 20 turns. There's a script in `source/tools/replayprofile/` which can plot a graph from that file.
     81
     82== Valgrind ==
     83
     84Callgrind with KCacheGrind is quite nice for detailed (though not hugely accurate) profiling. Valgrind often doesn't like !SpiderMonkey's JITs so you may have to use `valgrind --smc-check=all ...` if it otherwise crashes.