After learning to compile Simutrans, you may wish to change the code and see how it affects the game. As part of this process, it can be helpful to use a performance profiler. This stops the game many times every second to see which part of the code was just processed by the CPU(s) and then summarizes the totals. In this way, you can see what parts of the code are doing the most work.
how to compile Simutrans and you have compiled a debug version (uncommenting “DEBUG = 3” in config.default).
If you want to be able to read more debugging messages in simu.log, you can also set MSG_LEVEL = 3, but this will mean that you are profiling the debug build. In most cases you want the build that you are profiling to be as close as possible to a ‘normal’ build.
For debugging, you have to set the correct working directory, i.e. the directory where the pak/folders are located and use the -use_workdir command line option. You can also copy the /build/default/sim executable to your game directory. Changing the name to something like “simutrans-debug” is also recommended, to avoid any confusion.
Open a terminal and run:
sudo apt install perf
If you are lucky, perf may install immediately. But in Ubuntu, you will get an error message talking about your kernel version, presumably because perf is tightly tied to the kernel. Note your kernel version: we will use 5.4 as an example. Run this command, adjusted for your version number:
sudo apt update sudo apt install linux-5.4-tools-common sudo apt install linux-tools-common
If that doesn’t work and you are using another Debian distribution, try this instead (remembering to use your kernel version):
sudo apt install linux-perf-5.4
sudo zypper ref sudo zypper in perf
Arch Linux / Manjaro
sudo pacman -Syu perf
Open a terminal in your game directory and run:
sudo perf record -g ./simutrans-debug
Simutrans will load and you can play-test your changes. As you do this, perf will measure the game’s performance and generate logfiles. For reasons that will become clear later, you can only play for a short time: from my limited experience, perhaps one minute for every GiB of RAM in your system. If you want to test on a new map, it might be better to make your map before you start profiling. When you have reached your time limit, exit Simutrans in the normal way (saving if you want to).
It is common for Simutrans to crash when you are testing new code. When you are using perf, you may not be able to close a crashed program in the usual ways. If your build has “simutrans” in its name, then you can close the crashed Simutrans using pkill command:
sudo pkill -9 simutrans
Once this is done, perf will save its logs and close.
The traditional approach is to analyze the results as an ASCII graph. To do this, run the following in your game directory:
sudo perf report -g graph,0.05 --stdio > graph
After several minutes, this will generate a text file called graph that can be opened in any text editor. It’s possible to stop here. However, the graph is difficult to read, so the following steps will describe how to create an alternative called a flamegraph. But I recommend making an ASCII graph once to check that perf is working correctly, and that you have enough RAM, before you continue.
sudo apt install perl
Now download these Perl scripts to your game directory:
sudo perf script | ./stackcollapse-perf.pl > out.perf-folded sudo grep -v cpu_idle out.perf-folded | ./flamegraph.pl > debug.svg
Again, this conversion will take several minutes, though it requires less RAM than the traditional method.
Those commands should exclude functions which are stalled while waiting for I/O, so the results are biased towards ordinary play and away from the start-up process (especially if you are using a traditional hard drive). If loading and saving paksets or savegames is the part of Simutrans that you are interested in, then you may need to adjust this step.
The X axis shows how much time your CPU is spending on each function. For example, if half the X axis is used by main, then your CPU is spending half its time running that function. Note that the X axis is not chronological: it is showing you ‘how much’, not ‘when’.
The Y axis shows the relationship of different functions to each other. For example, the only real job of main() to call sysmain, which is therefore stacked on top of it.
You can hover over functions to see the exact percentage of CPU time that they used. You can click on functions to zoom in on them; you can zoom out again in the top left-hand corner. You can find particular functions using Ctrl+F or the ‘Search’ text in the top-right hand corner (click on ‘ic’ to toggle case sensitivity). This is essential for many Simutrans functions. Some functions are called by multiple functions (especially the _tpl templates), so use Search to make sure that you have identified all the calls. You can reset Search in the top right-hand corner of the graph.