Home | History | Annotate | Download | only in toolchain-utils
      1 #! /bin/bash -u
      2 # Copyright 2015 The Chromium OS Authors. All rights reserved.
      3 # Use of this source code is governed by a BSD-style license that can be
      4 # found in the LICENSE file.
      5 
      6 # This script first collects the addresses of the instructions being tracked by
      7 # the profile. After that, it calculates the offset of the addresses compared
      8 # to the base address and then gets the number of execution times for each
      9 # address. After that, it draws the heat map and the time map. A heap map shows
     10 # the overall hotness of instructions being executed while the time map shows the
     11 # hotness of instruction at different time.
     12 
     13 # binary : the name of the binary
     14 # profile : output of 'perf report -D'
     15 # loading_address  : the loading address of the binary
     16 # page_size : the size to be displayed, usually 4096(byte).
     17 
     18 if [[ $# -ne 4 ]]; then
     19      echo 'Illegal number of parameters' exit 1
     20 fi
     21 
     22 binary=$1
     23 profile=$2
     24 loading_address=$3
     25 page_size=$4
     26 
     27 # size of binary supported.
     28 binary_maximum=1000000000
     29 
     30 if ! [[ -e $profile ]] ; then
     31      echo "error: profile does not exist" >&2; exit 1
     32 fi
     33 
     34 re='^[0-9]+$'
     35 if ! [[ $page_size =~ $re ]] ; then
     36      echo "error: page_size is not a number" >&2; exit 1
     37 fi
     38 
     39 function test {
     40     "$@"
     41     local status=$?
     42     if [ $status -ne 0 ]; then
     43         echo "error with $1" >&2
     44     fi
     45     return $status
     46 }
     47 
     48 HEAT_PNG="heat_map.png"
     49 TIMELINE_PNG="timeline.png"
     50 
     51 test  grep -A 2 PERF_RECORD_SAMPLE $profile | grep -A 1 -B 1 "thread: $binary" | \
     52 grep -B 2 "dso.*$binary$" | awk -v base=$loading_address \
     53      "BEGIN { count=0; } /PERF_RECORD_SAMPLE/ {addr = strtonum(\$8) - strtonum(base); \
     54      if (addr < $binary_maximum) count++; \
     55      if (addr < $binary_maximum) print \$7,count,int(addr/$page_size)*$page_size}" >  out.txt
     56 
     57 
     58 test  awk '{print $3}' out.txt | sort -n | uniq -c > inst-histo.txt
     59 
     60 # generate inst heat map
     61 echo "
     62 set terminal png size 600,450
     63 set xlabel \"Instruction Virtual Address (MB)\"
     64 set ylabel \"Sample Occurance\"
     65 set grid
     66 
     67 set output \"${HEAT_PNG}\"
     68 set title \"Instruction Heat Map\"
     69 
     70 plot 'inst-histo.txt' using (\$2/1024/1024):1 with impulses notitle
     71 " | test gnuplot
     72 
     73 # generate instruction page access timeline
     74 num=$(awk 'END {print NR+1}' out.txt)
     75 
     76 echo "
     77 set terminal png size 600,450
     78 set xlabel \"time (sec)\"
     79 set ylabel \"Instruction Virtual Address (MB)\"
     80 
     81 set output \"${TIMELINE_PNG}\"
     82 set title \"instruction page accessd timeline\"
     83 
     84 plot 'out.txt' using (\$0/$num*10):(\$3/1024/1024) with dots notitle
     85 " | test gnuplot
     86