aboutsummaryrefslogtreecommitdiff
path: root/perf-to-inst-page.sh
diff options
context:
space:
mode:
Diffstat (limited to 'perf-to-inst-page.sh')
-rwxr-xr-xperf-to-inst-page.sh85
1 files changed, 85 insertions, 0 deletions
diff --git a/perf-to-inst-page.sh b/perf-to-inst-page.sh
new file mode 100755
index 00000000..ba1d2582
--- /dev/null
+++ b/perf-to-inst-page.sh
@@ -0,0 +1,85 @@
+#! /bin/bash -u
+# Copyright 2015 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# This script first collects the addresses of the instructions being tracked by
+# the profile. After that, it calculates the offset of the addresses compared
+# to the base address and then gets the number of execution times for each
+# address. After that, it draws the heat map and the time map. A heap map shows
+# the overall hotness of instructions being executed while the time map shows the
+# hotness of instruction at different time.
+
+# binary : the name of the binary
+# profile : output of 'perf report -D'
+# loading_address : the loading address of the binary
+# page_size : the size to be displayed, usually 4096(byte).
+
+if [[ $# -ne 4 ]]; then
+ echo 'Illegal number of parameters' exit 1
+fi
+
+binary=$1
+profile=$2
+loading_address=$3
+page_size=$4
+
+# size of binary supported.
+binary_maximum=1000000000
+
+if ! [[ -e $profile ]] ; then
+ echo "error: profile does not exist" >&2; exit 1
+fi
+
+re='^[0-9]+$'
+if ! [[ $page_size =~ $re ]] ; then
+ echo "error: page_size is not a number" >&2; exit 1
+fi
+
+function test {
+ "$@"
+ local status=$?
+ if [ $status -ne 0 ]; then
+ echo "error with $1" >&2
+ fi
+ return $status
+}
+
+HEAT_PNG="heat_map.png"
+TIMELINE_PNG="timeline.png"
+
+test grep -A 2 PERF_RECORD_SAMPLE $profile | grep -A 1 -B 1 "thread: $binary" | \
+grep -B 2 "dso.*$binary$" | awk -v base=$loading_address \
+ "BEGIN { count=0; } /PERF_RECORD_SAMPLE/ {addr = strtonum(\$8) - strtonum(base); \
+ if (addr < $binary_maximum) count++; \
+ if (addr < $binary_maximum) print \$7,count,int(addr/$page_size)*$page_size}" > out.txt
+
+
+test awk '{print $3}' out.txt | sort -n | uniq -c > inst-histo.txt
+
+# generate inst heat map
+echo "
+set terminal png size 600,450
+set xlabel \"Instruction Virtual Address (MB)\"
+set ylabel \"Sample Occurance\"
+set grid
+
+set output \"${HEAT_PNG}\"
+set title \"Instruction Heat Map\"
+
+plot 'inst-histo.txt' using (\$2/1024/1024):1 with impulses notitle
+" | test gnuplot
+
+# generate instruction page access timeline
+num=$(awk 'END {print NR+1}' out.txt)
+
+echo "
+set terminal png size 600,450
+set xlabel \"time (sec)\"
+set ylabel \"Instruction Virtual Address (MB)\"
+
+set output \"${TIMELINE_PNG}\"
+set title \"instruction page accessd timeline\"
+
+plot 'out.txt' using (\$0/$num*10):(\$3/1024/1024) with dots notitle
+" | test gnuplot