util.sh
#!/bin/bash
set -euo pipefail
if ! [ -x "$(command -v fz)" ]; then
echo 'Error: fz must be in PATH.' >&2
exit 1
fi
record_benchmark () {
APP=$1
LOG_FILE=$2
ADDITIONAL_ARGS=$3
echo "started benchmarking: $APP"
if [ -z "$ADDITIONAL_ARGS" ]
then
/usr/bin/time -o buildtime.txt -f "%e,%M" fz -XenableSetKeyword -c -o=a.out "$APP"
else
/usr/bin/time -o buildtime.txt -f "%e,%M" fz -XenableSetKeyword -c -o=a.out "$ADDITIONAL_ARGS" "$APP"
fi
# NYI benchmark warm or cold? Maybe we need this: sync; echo 3 > /proc/sys/vm/drop_caches
# NOTE: we rely on sth. like oom_reaper here. it should kill benchmarks that use too much memory.
/usr/bin/time -o runtime.txt -f "%e,%M" timeout --preserve-status --signal=15 --kill-after=70s 60s ./a.out
# sudo sysctl kernel.perf_event_paranoid=-1
# perf also supports running average power limit (RAPL) for power consumption measurements
# Paper: Ranking Programming Languages by Energy Efficiency https://haslab.github.io/SAFER/scp21.pdf
sudo -n sysctl kernel.perf_event_paranoid=-1 || echo "failure setting perf_event_paranoid"
perf stat -o perf_stat_general.txt -x ',' -e task-clock,context-switches,cpu-migrations,page-faults,cpu-cycles,instructions,branches,branch-misses,branch-instructions,bus-cycles,cache-misses,cache-references,ref-cycles timeout --preserve-status --signal=15 --kill-after=70s 60s ./a.out
perf stat -o perf_stat_energy.txt -x ',' -e power/energy-pkg/ timeout --preserve-status --signal=15 --kill-after=70s 60s ./a.out
{
echo "# FORMAT: "
echo "# date, build time (seconds), build memory usage (kilobyte), run time (seconds), run memory usage (kilobyte), c code source size (bytes), binary size (bytes), fz version, additional args, task-clock,context-switches,cpu-migrations,page-faults,cpu-cycles,instructions, branches,branch-misses,branch-instructions,bus-cycles,cache-misses,cache-references,ref-cycles, energy usage (joule)"
echo -n "$(date --iso-8601='minutes'),"
echo -n "$(cat buildtime.txt),"
echo -n "$(cat runtime.txt),"
echo -n "$(cat ./a.out.c | wc -c),"
echo -n "$(cat ./a.out | wc -c),"
echo -n " # $(fz -version),"
if [ -z "$ADDITIONAL_ARGS" ]
then
echo -n ","
else
echo -n "$ADDITIONAL_ARGS,"
fi
# sed: remove everything after first comma, grep: select only lines starting with a digit, tr: remove all line breaks
sed 's/,.*/,/g' perf_stat_general.txt | grep -E '^[0-9]' | tr -d '\n'
sed 's/,.*/,/g' perf_stat_energy.txt | grep -E '^[0-9]' | tr -d '\n'
} >> "$LOG_FILE"
# new line
echo "" >> "$LOG_FILE"
rm buildtime.txt runtime.txt perf_stat_general.txt perf_stat_energy.txt ./a.out ./a.out.c
echo "finished benchmarking: $APP"
}