Engine Profiling: Difference between revisions

From Spring
Jump to navigationJump to search
Hoijui (talk | contribs)
No edit summary
Hoijui (talk | contribs)
cleanup
Line 40: Line 40:
'''Recommended settings'''
'''Recommended settings'''


Use a call-graph depth of 16, disable kernel profiling and enable user-space profiling, separate each thread and application in its own profile. You can always merge them later, using ''opreport''.
* use a call-graph depth of size 16
* disable kernel profiling & enable user-space profiling
* separate each application in its own profile
* separate each thread in its own profile; you can always merge them later, using ''opreport''




'''A typical profiling session'''
'''A typical profiling session'''


<font color="#00EE00">
<code><pre>
<code><pre>
# We need to be root
# We need to be root
Line 73: Line 75:
opcontrol --dump
opcontrol --dump
</pre></code>
</pre></code>
</font>
 


=== Post processing ''oprof'' data ===
=== Post processing ''oprof'' data ===


''oprofile'' indexes stuff by thread id and process id since the setting i've made you use did tell it to do so  :p
With the settings we used above, ''oprofile'' indexes stuff by thread- and process-ID. In order to generate a report, we will have to tell which program, which threads and which sampling sessions to include.
so in order to generate a report, you'll have to tell which program, which threads to include, and which sampling sessions
If you do not care much, you can just merge thread data and sampling data.
if you do not care much, you can just merge thread data and sampling data
 
 
'''Extract the data'''


<font color="#00EE00">
<code><pre>
<code><pre>
BIN_PATH=~/Projects/spring/installs/cmake/master/linux64/debug/spring
BIN_PATH=~/Projects/spring/installs/cmake/master/linux64/debug/spring
DATA_FILE_PATH=./springProfilingData.oprof
DATA_FILE_PATH=./springProfilingData.oprof
# these two will be used later
GRAPH_FILE_PATH=./springProfilingGraph.dot
GRAPH_FILE_PATH=./springProfilingGraph.dot
IMAGE_FILE_PATH=./springProfilingGraph.png
IMAGE_FILE_PATH=./springProfilingGraph.png
Line 100: Line 104:
         --output-file ${DATA_FILE_PATH}
         --output-file ${DATA_FILE_PATH}
</pre></code>
</pre></code>
</font>


<code>--callgraph</code> tells it to plot a full call-graph table, which can be parsed by other tools
<code>--callgraph</code> tells it to plot a full call-graph table, which can be parsed by other tools.
if instead you want a flat txt table, omit it
If instead you want a flat CSV table, omit it.
 
 
'''Converting the data file to a dot-graph file'''


[https://code.google.com/p/jrfonseca/wiki/Gprof2Dot gprof2dot] takes ''oprof'' data and outputs a nice dot-graph.
[https://code.google.com/p/jrfonseca/wiki/Gprof2Dot gprof2dot] takes ''oprof'' data and outputs a nice dot-graph.
To generate the dot graph out of the <code>--callgraph</code> version:
To generate the dot graph out of the <code>--callgraph</code> version, use this command:
<font color="#00EE00">
<code><pre>
<code><pre>
gprof2dot --format=oprofile -o=${GRAPH_FILE_PATH} ${DATA_FILE_PATH}
gprof2dot --format=oprofile -o=${GRAPH_FILE_PATH} ${DATA_FILE_PATH}
</pre></code>
</pre></code>
</font>


Then you can either use xdot to view it, or use dot to generate a png or svg pic
Then you can either use [https://code.google.com/p/jrfonseca/wiki/XDot XDot] to view it directly, or create an image out of the graph file.


Then you can use either graphviz's ''dot'' utility to render to an image, or display the graph directly, for example with [https://code.google.com/p/jrfonseca/wiki/XDot xdot].
 
'''Createing an image out of the graph file'''
 
We will use [http://www.graphviz.org/ GraphViz]'s ''dot'' utility to render to an image.


<code><pre>
<code><pre>
dot -Tpng ${GRAPH_FILE_PATH} > ${IMAGE_FILE_PATH}
dot -Tpng ${GRAPH_FILE_PATH} > ${IMAGE_FILE_PATH}
</pre></code>
</pre></code>
The <code>-Tpng</code> part can be replaced by <code>-Tsvg</code>, <code>-Tgif</code> and more.
The result will look about like this:
The result will look about like this:
http://wiki.jrfonseca.googlecode.com/hg/xdot-profile2.png
http://wiki.jrfonseca.googlecode.com/hg/xdot-profile2.png

Revision as of 11:31, 16 November 2010

Development < Engine Profiling

Engine Profiling

Linux

Intro

There are several ways to profile an application.

gprof

The compiler injects special code in the binary that self profiles it when it runs. this is what cmake -DCMAKE_BUILD_TYPE=PROFILING is here for. We are not going to use this. It does not interfere with normal program's work-flow. With spring, it gets so slow that it is unusable for profiling anything in late game (which is where it is needed the most). It requires special compiling options.


oprof

OProfile uses statistical sampling. It is a kernel module, which every n clock ticks, registers which function is currently being processed. It is lightweight; it may run with almost 0 performance impact. This method always profiles your profiles your whole system; relevant info has to be filtered out after the profiling run has finished. The downside of statistical profiling, is that it requires at least a certain sample size to achieve good accuracy. Also remember, that oprof still requires the debug symbols, to resolve addresses into function names. It can be turned on/off at any time, so for instance, you may skip spring loading so you would only profile in-game runtime. You can also merge multiple profiling sessions.

Setting up oprof

Required stuff:

  • oprof kernel module
  • oprof package

Using oprof

Note: Modern CPUs have special statistical sampling timing functions to make profiling with software like oprof fast.

You will have to load the kernel module. The profiling daemon is controlled using opcontrol as root. As regular user, you can do post-processing using opreport.


Recommended settings

  • use a call-graph depth of size 16
  • disable kernel profiling & enable user-space profiling
  • separate each application in its own profile
  • separate each thread in its own profile; you can always merge them later, using opreport


A typical profiling session

# We need to be root
su -

# In case the kernel module is not already loaded ...
insmod oprofile

# This has to be sent only once; it will be saved
opcontrol --event=CPU_CLK_UNHALTED:1000000:0x0:0:1 \
          --callgraph=16 \
          --separate=thread,library \
          --no-vmlinux

# -- Bring spring into a state where you want to start profiling --

# start the profiler
opcontrol --start

# -- In spring, do whatever you want to profile --

# stop the profiler
opcontrol --stop

# in order to make the profile data available to user-space,
# you have to dump the data
opcontrol --dump


Post processing oprof data

With the settings we used above, oprofile indexes stuff by thread- and process-ID. In order to generate a report, we will have to tell which program, which threads and which sampling sessions to include. If you do not care much, you can just merge thread data and sampling data.


Extract the data

BIN_PATH=~/Projects/spring/installs/cmake/master/linux64/debug/spring
DATA_FILE_PATH=./springProfilingData.oprof
# these two will be used later
GRAPH_FILE_PATH=./springProfilingGraph.dot
IMAGE_FILE_PATH=./springProfilingGraph.png

# Caution: this would take a long time!
#          ~ 3h for a spring in-game time of 5min
#         --debug-info \
#          without it, it shrinks to ~ 10s
opreport \
         --long-filenames \
         --callgraph \
         --demangle=smart \
         --merge=tid,tgid \
         --symbols ${BIN_PATH} \
         --output-file ${DATA_FILE_PATH}

--callgraph tells it to plot a full call-graph table, which can be parsed by other tools. If instead you want a flat CSV table, omit it.


Converting the data file to a dot-graph file

gprof2dot takes oprof data and outputs a nice dot-graph. To generate the dot graph out of the --callgraph version, use this command:

gprof2dot --format=oprofile -o=${GRAPH_FILE_PATH} ${DATA_FILE_PATH}

Then you can either use XDot to view it directly, or create an image out of the graph file.


Createing an image out of the graph file

We will use GraphViz's dot utility to render to an image.

dot -Tpng ${GRAPH_FILE_PATH} > ${IMAGE_FILE_PATH}

The -Tpng part can be replaced by -Tsvg, -Tgif and more.

The result will look about like this: xdot-profile2.png


Windows

<Please add>