Trace MRI method cache hit rate
#!/bin/bash | |
# | |
# Uses ftrace user probes to collect and display method cache statistics from a given | |
# MRI binary. The script sleeps for a specified amount of time to collect data from | |
# any MRI process that is running on the system. | |
# | |
# Usage: trace_rb_method_cache.sh <ruby_binary> <sleep_time> | |
# | |
# Caveats: Linux only, must be run as root, requires ftrace, only tested on Ruby 2.1. | |
# | |
TRACE_DIR=/sys/kernel/debug/tracing | |
[[ $(id -u) != "0" ]] && echo "this script must be run as root" && exit 1 | |
[[ -z $1 || -z $2 || ! -f $1 ]] && echo "usage: $0 <ruby_binary> <sleep_time>" && exit 1 | |
[[ ! -d $TRACE_DIR ]] && echo "$TRACE_DIR does not exist - do you have ftrace enabled?" && exit 1 | |
RUBY_BIN=$1 | |
SLEEP_TIME=$2 | |
# attempt to find the hit and miss addresses | |
readarray MISS_HIT_ADDR < <(\ | |
gdb --batch -ex 'disas rb_method_entry' $RUBY_BIN | \ | |
awk '/rb_method_entry_get_without_cache/ && $3 == "jmpq" { miss_addr=$1 } /retq/ { hit_addr=$1 } END { if (hit_addr && miss_addr) printf "%s\n%s\n", miss_addr, hit_addr }' \ | |
) | |
[ -z $MISS_HIT_ADDR] && echo "unable to determine cache hit/miss addresses from $RUBY_BIN" && exit 1 | |
cd /sys/kernel/debug/tracing | |
# clear current tracer | |
echo 0 > tracing_on | |
echo > uprobe_events | |
# set up | |
echo nop > current_tracer | |
echo "p:rb_method_entry_miss $RUBY_BIN:${MISS_HIT_ADDR[0]}" >> uprobe_events | |
echo "p:rb_method_entry_hit $RUBY_BIN:${MISS_HIT_ADDR[1]}" >> uprobe_events | |
echo 1 > events/uprobes/enable | |
echo 1 > tracing_on | |
sleep $SLEEP_TIME | |
# report | |
echo 0 > tracing_on | |
echo 0 > events/uprobes/enable | |
cat uprobe_profile | awk '/miss/ { miss=$3; printf "%-10s %8d\n", "misses:", $3 } /hit/ { hit=$3; printf "%-10s %8d\n", "hits:", $3 } END { if (hit + miss > 0) printf "%-10s %7.2f%%\n", "hit rate:", (hit / (hit + miss)) * 100 }' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This comment has been minimized.
There's a bug in this script. If
write(2)
fails to write to theftrace
VFSbash
'secho
won't fail, you should use/bin/echo
instead. docs You should also useset -e
, so it'll bail in that case.