diff --git a/tools/poor-profiler/README.md b/tools/poor-profiler/README.md new file mode 100644 index 0000000000000000000000000000000000000000..42e2e4b1750e8a4a0097940f6bbb67f405c2a079 --- /dev/null +++ b/tools/poor-profiler/README.md @@ -0,0 +1,37 @@ +poor-profiler +------------- +This is a (rather poor) attempt at building a profiler for card10. The +idea is based on the [poor man's profiler](https://poormansprofiler.org/). +Essentially, it uses stack-traces gathered using GDB. This means, +execution will be significantly slowed down which might make certain +features of the firmware misbehave. Use with care! + +That said, here is how to use it: + +1. Configure the profiler by adjusting `nsamples` and `sleeptime` in + [`poor-profiler.sh`](https://git.card10.badge.events.ccc.de/card10/firmware/blob/master/tools/poor-profiler/poor-profiler.sh). + (If anyone wants to send a patch which makes this script use proper + commandline args, please do!) +2. Start profiling! Just call + ```bash + ./tools/poor-profiler/poor-profiler.sh >/tmp/samples + ``` + from the firmware repository root. +3. Next, collapse the samples using the + [`poor-collapse.sh`](https://git.card10.badge.events.ccc.de/card10/firmware/blob/master/tools/poor-profiler/poor-collapse.sh) + script: + ```bash + $ ./tools/poor-profiler/poor-collapse.sh /tmp/samples >/tmp/samples.collapsed + ``` +4. Finally, feed the collapsed samples into the Brendan Gregg's + [FlameGraph](https://github.com/brendangregg/FlameGraph) script which + will create an svg you can view (and interact with!) in your browser: + ```bash + $ /path/to/FlameGraph/flamegraph.pl /tmp/samples.collapsed >/tmp/flamegraph.svg + $ firefox /tmpflamegraph.svg + ``` + (If you feel that a perl script is not modern enough, you can also use + [`inferno-flamegraph`](https://github.com/jonhoo/inferno) which is + written in Rust ...) + +Happy profiling! diff --git a/tools/poor-profiler/poor-collapse.sh b/tools/poor-profiler/poor-collapse.sh new file mode 100755 index 0000000000000000000000000000000000000000..6e6af32d53d2d5472a20d4c4d3069f8fc0e2e8cf --- /dev/null +++ b/tools/poor-profiler/poor-collapse.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +cat "$1" | \ + sort | \ + uniq -c | \ + sort -r -n -k 1,1 | \ + sed 's/^ \+\([0-9]\+\) \(.*\)$/\2 \1/g' | \ + sort diff --git a/tools/poor-profiler/poor-profiler.sh b/tools/poor-profiler/poor-profiler.sh new file mode 100755 index 0000000000000000000000000000000000000000..91179b0d2c7e8ed4737b1a60880391bff215679f --- /dev/null +++ b/tools/poor-profiler/poor-profiler.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +nsamples=4096 +sleeptime=0.05 + +for x in $(seq 1 $nsamples); do + printf "Capturing %6u/%u ...\n" "$x" "$nsamples" >&2 + arm-none-eabi-gdb -nx -x init.gdb -ex "set pagination 0" -ex "bt" -ex "continue&" -batch build/epicardium/epicardium.elf 2>/dev/null | \ + grep -E '^#' | \ + tac | \ + sed 's/^#[0-9]\+ \+0x.* in \(.*\) (.*$/\1/g;s/^#[0-9]\+ \+\(.*\) (.*$/\1/g' | \ + tr '\n' ';' | \ + sed 's/^\(.*\);$/\1\n/g' + sleep $sleeptime +done