OSDN Git Service

Merge "Add timing of allocation functions." am: 3d614a17ef am: 77b1d6fcf2
authorChristopher Ferris <cferris@google.com>
Wed, 21 Oct 2015 20:04:03 +0000 (20:04 +0000)
committerandroid-build-merger <android-build-merger@google.com>
Wed, 21 Oct 2015 20:04:03 +0000 (20:04 +0000)
am: 8be4728496

* commit '8be4728496befae5d54850d32667adca3d16f7e0':
  Add timing of allocation functions.

ext4_utils/allocate.c
ext4_utils/make_ext4fs.c
tests/binder/benchmarks/binderAddInts.cpp
tests/workloads/chromefling.sh [new file with mode: 0755]
tests/workloads/defs.sh
tests/workloads/powerave.py [new file with mode: 0755]
tests/workloads/pwrsummary.sh [new file with mode: 0755]
tests/workloads/pwrtest.sh [new file with mode: 0755]
tests/workloads/recentfling.sh
tests/workloads/systemapps.sh
tests/workloads/youtube.sh [new file with mode: 0755]

index cca3dc1..d18aec5 100644 (file)
@@ -307,7 +307,7 @@ static void init_bg(struct block_group_info *bg, unsigned int i)
        bg->first_free_block = 0;
        bg->free_inodes = info.inodes_per_group;
        bg->first_free_inode = 1;
-       bg->flags = EXT4_BG_INODE_UNINIT;
+       bg->flags = 0;
 
        if (reserve_blocks(bg, bg->first_free_block, bg->header_blocks) < 0)
                error("failed to reserve %u blocks in block group %u\n", bg->header_blocks, i);
index b4ebbce..a8a2617 100644 (file)
@@ -566,8 +566,7 @@ int make_ext4fs_internal(int fd, const char *_directory, const char *_target_out
 
        info.feat_ro_compat |=
                        EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER |
-                       EXT4_FEATURE_RO_COMPAT_LARGE_FILE |
-                       EXT4_FEATURE_RO_COMPAT_GDT_CSUM;
+                       EXT4_FEATURE_RO_COMPAT_LARGE_FILE;
 
        info.feat_incompat |=
                        EXT4_FEATURE_INCOMPAT_EXTENTS |
index e4ddcfa..69e47ff 100644 (file)
@@ -36,6 +36,7 @@
 #include <cerrno>
 #include <grp.h>
 #include <iostream>
+#include <iomanip>
 #include <libgen.h>
 #include <time.h>
 #include <unistd.h>
@@ -88,8 +89,23 @@ class AddIntsService : public BBinder
     int cpu_;
 };
 
+struct Duration {
+    double value;
+    friend std::ostream& operator<<(std::ostream& stream, const Duration& d) {
+        static const char *SUFFIXES[] = {"s", "ms", "us", "ns"};
+        size_t suffix = 0;
+        double temp = d.value;
+        while (temp < .1 && suffix < 3) {
+            temp *= 1000;
+            suffix++;
+        }
+        stream << temp << SUFFIXES[suffix];
+        return stream;
+    }
+};
+
 // File scope function prototypes
-static void server(void);
+static bool server(void);
 static void client(void);
 static void bindCPU(unsigned int cpu);
 static ostream &operator<<(ostream &stream, const String16& str);
@@ -196,7 +212,7 @@ int main(int argc, char *argv[])
         return 0;
 
     default: // Parent
-        server();
+        if (!server()) { break; }
 
         // Wait for all children to end
         do {
@@ -219,7 +235,7 @@ int main(int argc, char *argv[])
     return 0;
 }
 
-static void server(void)
+static bool server(void)
 {
     int rv;
 
@@ -230,10 +246,12 @@ static void server(void)
         new AddIntsService(options.serverCPU))) != 0) {
         cerr << "addService " << serviceName << " failed, rv: " << rv
             << " errno: " << errno << endl;
+        return false;
     }
 
     // Start threads to handle server work
     proc->startThreadPool();
+    return true;
 }
 
 static void client(void)
@@ -248,12 +266,17 @@ static void client(void)
 
     // Attach to service
     sp<IBinder> binder;
-    do {
+    for (int i = 0; i < 3; i++) {
         binder = sm->getService(serviceName);
         if (binder != 0) break;
         cout << serviceName << " not published, waiting..." << endl;
         usleep(500000); // 0.5 s
-    } while(true);
+    }
+
+    if (binder == 0) {
+        cout << serviceName << " failed to publish, aborting" << endl;
+        return;
+    }
 
     // Perform the IPC operations
     for (unsigned int iter = 0; iter < options.iterations; iter++) {
@@ -298,9 +321,10 @@ static void client(void)
     }
 
     // Display the results
-    cout << "Time per iteration min: " << min
-        << " avg: " << (total / options.iterations)
-        << " max: " << max
+    cout << fixed << setprecision(2)
+        << "Time per iteration min: " << Duration{min}
+        << " avg: " << Duration{total / options.iterations}
+        << " max: " << Duration{max}
         << endl;
 }
 
diff --git a/tests/workloads/chromefling.sh b/tests/workloads/chromefling.sh
new file mode 100755 (executable)
index 0000000..a86f274
--- /dev/null
@@ -0,0 +1,160 @@
+#
+# Script to start 3 chrome tabs, fling each of them, repeat
+# For each iteration, Total frames and janky frames are reported.
+#
+# Options are described below.
+#
+iterations=10
+startapps=1
+capturesystrace=0
+waittime=4
+app=chrome
+
+function processLocalOption {
+       ret=0
+       case "$1" in
+       (-N) startapps=0;;
+       (-A) unset appList;;
+       (-L) appList=$2; shift; ret=1;;
+       (-T) capturesystrace=1;;
+       (-W) waittime=$2; shift; ret=1;;
+       (*)
+               echo "$0: unrecognized option: $1"
+               echo; echo "Usage: $0 [options]"
+               echo "-A : use all known applications"
+               echo "-L applist : list of applications"
+               echo "   default: $appList"
+               echo "-N : no app startups, just fling"
+               echo "-g : generate activity strings"
+               echo "-i iterations"
+               echo "-T : capture systrace on each iteration"
+               echo "-d device : device type (shamu, volantis, bullhead,...)"
+               exit 1;;
+       esac
+       return $ret
+}
+
+CMDDIR=$(dirname $0 2>/dev/null)
+CMDDIR=${CMDDIR:=.}
+. $CMDDIR/defs.sh
+
+case $DEVICE in
+(hammerhead)
+       flingtime=300
+       downCount=2
+       upCount=6
+       UP="70 400 70 100 $flingtime"
+       DOWN="70 100 70 400 $flingtime";;
+(shamu)
+       flingtime=100
+       downCount=2 
+       upCount=2
+       UP="700 1847 700 400 $flingtime"
+       DOWN="700 400 700 1847 $flingtime";;
+(angler)
+       flingtime=150
+       downCount=4
+       upCount=3
+       UP="500 1200 500 550 $flingtime"
+       DOWN="500 550 500 1200 $flingtime";;
+(bullhead|volantis)
+       flingtime=200
+       downCount=5
+       upCount=5
+       UP="500 1400 500 400 $flingtime"
+       DOWN="500 400 500 1400 $flingtime";;
+(*)
+       echo "Error: No display information available for $DEVICE"
+       exit 1;;
+esac
+
+function swipe {
+       count=0
+       while [ $count -lt $2 ]
+       do
+               doSwipe $1
+               ((count=count+1))
+       done
+       sleep 1
+}
+
+cur=1
+frameSum=0
+jankSum=0
+latency90Sum=0
+latency95Sum=0
+latency99Sum=0
+
+doKeyevent HOME
+sleep 0.5
+resetJankyFrames $(getPackageName $app)
+
+while [ $cur -le $iterations ]
+do
+       if [ $capturesystrace -gt 0 ]; then
+               ${ADB}atrace --async_start -z -c -b 16000 freq gfx view idle sched
+       fi
+       t=$(startActivity $app)
+       sleep $waittime
+       swipe "$UP" $upCount
+
+       t=$(startActivity $app)
+       sleep $waittime
+       swipe "$UP" $upCount
+
+       t=$(startActivity $app)
+       sleep $waittime
+       swipe "$UP" $upCount
+
+       doKeyevent BACK
+       sleep $waittime
+       swipe "$DOWN" $downCount
+
+       doKeyevent BACK
+       sleep $waittime
+       swipe "$DOWN" $downCount
+
+       doKeyevent BACK
+       sleep 0.5
+
+       if [ $capturesystrace -gt 0 ]; then
+               ${ADB}atrace --async_dump -z -c -b 16000 freq gfx view idle sched > trace.${cur}.out
+       fi
+       doKeyevent HOME
+       sleep 0.5
+
+       set -- $(getJankyFrames $(getPackageName $app))
+       totalDiff=$1
+       jankyDiff=$2
+       latency90=$3
+       latency95=$4
+       latency99=$5
+       if [ ${totalDiff:=0} -eq 0 ]; then
+               echo Error: could not read frame info with \"dumpsys gfxinfo\"
+               exit 1
+       fi
+
+       ((frameSum=frameSum+totalDiff))
+       ((jankSum=jankSum+jankyDiff))
+       ((latency90Sum=latency90Sum+latency90))
+       ((latency95Sum=latency95Sum+latency95))
+       ((latency99Sum=latency99Sum+latency99))
+       if [ "$totalDiff" -eq 0 ]; then
+               echo Error: no frames detected. Is the display off?
+               exit 1
+       fi
+       ((jankPct=jankyDiff*100/totalDiff))
+       resetJankyFrames $(getPackageName $app)
+
+
+       echo Frames: $totalDiff latency: $latency90/$latency95/$latency99 Janks: $jankyDiff\(${jankPct}%\)
+       ((cur=cur+1))
+done
+doKeyevent HOME
+((aveJankPct=jankSum*100/frameSum))
+((aveJanks=jankSum/iterations))
+((aveFrames=frameSum/iterations))
+((aveLatency90=latency90Sum/iterations))
+((aveLatency95=latency95Sum/iterations))
+((aveLatency99=latency99Sum/iterations))
+echo AVE: Frames: $aveFrames latency: $aveLatency90/$aveLatency95/$aveLatency99 Janks: $aveJanks\(${aveJankPct}%\)
index a2b7138..0f50fe1 100755 (executable)
@@ -16,15 +16,16 @@ youtubeActivity='com.google.android.youtube/com.google.android.apps.youtube.app.
 cameraActivity='com.google.android.GoogleCamera/com.android.camera.CameraActivity'
 playActivity='com.android.vending/com.google.android.finsky.activities.MainActivity'
 feedlyActivity='com.devhd.feedly/com.devhd.feedly.Main'
-photosActivity='com.google.android.apps.plus/com.google.android.apps.photos.phone.PhotosHomeActivity'
+photosActivity='com.google.android.apps.photos/com.google.android.apps.photos.home.HomeActivity'
 mapsActivity='com.google.android.apps.maps/com.google.android.maps.MapsActivity'
 calendarActivity='com.google.android.calendar/com.android.calendar.AllInOneActivity'
 earthActivity='com.google.earth/com.google.earth.EarthActivity'
-calculatorActivity='com.android.calculator2/com.android.calculator2.Calculator'
+calculatorActivity='com.google.android.calculator/com.android.calculator2.Calculator'
 sheetsActivity='com.google.android.apps.docs.editors.sheets/com.google.android.apps.docs.app.NewMainProxyActivity'
 docsActivity='com.google.android.apps.docs.editors.docs/com.google.android.apps.docs.app.NewMainProxyActivity'
 operaActivity='com.opera.mini.native/com.opera.mini.android.Browser'
 firefoxActivity='org.mozilla.firefox/org.mozilla.firefox.App'
+suntempleActivity='com.BrueComputing.SunTemple/com.epicgames.ue4.GameActivity'
 homeActivity='com.google.android.googlequicksearchbox/com.google.android.launcher.GEL'
 
 function showUsage {
@@ -97,6 +98,18 @@ else
        isOnDevice=0
 fi
 
+if [ $isOnDevice -gt 0 ]; then
+       case "$DEVICE" in
+       (bullhead|angler)
+               if ! echo $$ > /dev/cpuset/background/tasks; then
+                       echo Could not put PID $$ in background
+               fi
+               ;;
+       (*)
+               ;;
+       esac
+fi
+
 # default values if not set by options or calling script
 appList=${appList:=$dfltAppList}
 savetmpfiles=${savetmpfiles:=0}
@@ -109,7 +122,9 @@ ADB=${ADB:=""}
 output=${output:="./out"}
 
 # clear the output file
-> $output
+if [ -f $output ]; then
+       > $output
+fi
 
 # ADB commands
 AM_FORCE_START="${ADB}am start -W -S"
@@ -162,6 +177,7 @@ function log2msec {
        in=$1
        in=${in:=0.0}
        set -- $(echo $in | tr . " ")
+
        # shell addition via (( )) doesn't like leading zeroes in msecs
        # field so remove leading zeroes
        msecfield=$(expr 0 + $2)
@@ -209,7 +225,7 @@ function getEndTime {
 
 function resetJankyFrames {
        _gfxapp=$1
-       _gfxapp=${app:="com.android.systemui"}
+       _gfxapp=${_gfxapp:="com.android.systemui"}
        ${ADB}dumpsys gfxinfo $_gfxapp reset 2>&1 >/dev/null
 }
 
@@ -256,14 +272,21 @@ function checkForDirectReclaim {
 }
 
 function startInstramentation {
+       _iter=$1
+       _iter=${_iter:=0}
+       enableAtrace=$2
+       enableAtrace=${enableAtrace:=1}
        # Called at beginning of loop. Turn on instramentation like atrace
        vout start instramentation $(date)
        echo =============================== >> $output
-       echo Before iteration >> $output
+       echo Before iteration $_iter >> $output
        echo =============================== >> $output
        ${ADB}cat /proc/meminfo 2>&1 >> $output
        ${ADB}dumpsys meminfo 2>&1 >> $output
-       if [ "$user" = root ]; then
+       if [ "$DEVICE" = volantis ]; then
+               ${ADB}cat /d/nvmap/iovmm/procrank 2>&1 >> $output
+       fi
+       if [ "$user" = root -a $enableAtrace -gt 0 ]; then
                vout ${ADB}atrace -b 32768 --async_start $tracecategories
                ${ADB}atrace -b 32768 --async_start $tracecategories >> $output
                echo >> $output
@@ -271,14 +294,15 @@ function startInstramentation {
 }
 
 function stopInstramentation {
-       if [ "$user" = root ]; then
+       enableAtrace=$1
+       enableAtrace=${enableAtrace:=1}
+       if [ "$user" = root -a $enableAtrace -gt 0 ]; then
                vout ${ADB}atrace --async_stop
                ${ADB}atrace --async_stop > /dev/null
        fi
 }
 
 function stopAndDumpInstramentation {
-       # Called at beginning of loop. Turn on instramentation like atrace
        vout stop instramentation $(date)
        echo =============================== >> $output
        echo After iteration >> $output
@@ -300,9 +324,9 @@ function stopAndDumpInstramentation {
                        python $UNCOMPRESS $tmpTrace >> $traceout
                        rm -f $tmpTrace
                else
-                       ${ADB}atrace $zarg -b 32768 --async_dump >> $traceout
+                       ${ADB}atrace -b 32768 --async_dump > $traceout
                fi
-               vout ${ADB}atrace $zarg --async_dump
+               vout ${ADB}atrace $zarg -b 32768 --async_dump
                vout ${ADB}atrace --async_stop
                ${ADB}atrace --async_stop > /dev/null
        fi
@@ -375,7 +399,14 @@ function checkActivity {
 
 function doSwipe {
        vout ${ADB}input swipe $*
-       ${ADB}input swipe $*
+       ${ADB}nice input swipe $*
+}
+
+function doText {
+       echo $* > ./tmpOutput
+       vout ${ADB}input text \"$*\"
+       ${ADB}input text "$(cat ./tmpOutput)"
+       rm -f ./tmpOutput
 }
 
 function doTap {
diff --git a/tests/workloads/powerave.py b/tests/workloads/powerave.py
new file mode 100755 (executable)
index 0000000..4d786b9
--- /dev/null
@@ -0,0 +1,46 @@
+#!/usr/bin/python
+
+import sys
+import getopt
+
+def usage():
+    print "powersum.py [OPTIONS] HZ VOLTAGE [FILE]"
+    print "OPTIONS: "
+    print "-o OFFSET: subtract OFFSET from all data points"
+    print "\nHZ: samples per second in FILE or stdin"
+    sys.exit(0)
+
+offset = 0.0
+voltage = 4.3
+
+parsedargv,argvrem = getopt.getopt(sys.argv[1:], "vo:w:l:h", ["help"])
+for o,a in parsedargv:
+    if o == '-o': offset = float(a)
+    if o == '-h' or o == '--help': usage()
+
+hz = float(argvrem[0])
+voltage = float(argvrem[1])
+if len(argvrem) > 1:
+    f = open(argvrem[2], "r")
+else:
+    f = sys.stdin
+
+totalpower = 0.0
+samplectr = 0
+
+for line in f:
+    try:
+        val = float(line.split(" ")[1]) # xxx take 2nd arg in line
+        val -= offset
+    except:
+        print "Can't parse data line, did you remember the timestamp?"
+        print "data was: %s" % line
+        sys.exit(1)
+
+    samplectr+=1
+    totalpower += val/hz
+
+avecurrent = totalpower * hz *1000 / samplectr
+avepower = avecurrent * voltage
+
+print "%.3f %.3f" % (avecurrent, avepower)
diff --git a/tests/workloads/pwrsummary.sh b/tests/workloads/pwrsummary.sh
new file mode 100755 (executable)
index 0000000..3d3aeb8
--- /dev/null
@@ -0,0 +1,235 @@
+# print summary of output generated by pwrtest.sh
+#
+# default results directories are <device>-<date>[-experiment]. By default
+# match any device and the year 201*.
+#
+# Examples:
+#
+# - show output for all bullhead tests in july 2015:
+#    ./pwrsummary.sh -r "bh-201507*"
+#
+# - generate CSV file for import into spreadsheet:
+#    ./pwrsummary.sh -o csv
+#
+
+CMDDIR=$(dirname $0 2>/dev/null)
+CMDDIR=${CMDDIR:=.}
+cd $CMDDIR
+CMDDIR=$(pwd)
+cd -
+POWERAVE="python $CMDDIR/powerave.py"
+
+defaultPattern="*-201*"
+defaultVoltage=4.3
+defaultFrequency=5
+
+function Usage {
+       echo "$0 [-o format] [-v voltage] [-h freq] [-f resultsDirectories]"
+}
+
+while [ $# -gt 0 ]
+do
+       case "$1" in
+       (-o) format=$2; shift;;
+       (-v) voltage=$2; shift;;
+       (-h) hz=$2; shift;;
+       (-r) testResults="$2"; shift;;
+       (--help) Usage; exit 0;;
+       (--) shift; break;;
+       (*)
+               echo Unknown option: $1
+               Usage
+               exit 1;;
+       esac
+       shift
+done
+
+testResults=${testResults:=$defaultPattern}
+voltage=${voltage:=$defaultVoltage}
+hz=${hz:=$defaultFrequency}
+
+function printHeader {
+       workload=$1
+       units="unknown"
+       case $workload in
+       (suntemple|shadowgrid2)
+               units="FPS";;
+       (recentfling|youtube|chrome)
+               units="FPS from app point of view: 1/(90th percentile render time)";;
+       (sysapps)
+               units="App start/switch per second";;
+       esac
+
+       echo "Performance unit for $workload is: $units"
+       if [ "$format" = csv ]; then
+               printf "%s,%s,%s,%s,%s,%s,%s,%s,%s\n" " " build min ave max net-mA@${voltage}v base-mW net-mW perf/W
+       else
+               printf "%-30s %-8s %12.12s %12.12s %12.12s %12.12s %12.12s %12.12s %12.12s\n" " " build min ave max net-mA@${voltage}v base-mW net-mW perf/W
+       fi
+}
+
+function average {
+       awk 'BEGIN { count=0; sum=0; max=-1000000000; min=1000000000; }
+       {
+               cur = $1;
+               sum = sum + cur; 
+               if (cur > max) max = cur;
+               if (cur < min) min = cur;
+               count++;
+       }
+
+       END {
+               if (count > 0) {
+                       ave = sum / count;
+                       printf "%.2f %.2f %.2f\n", min, ave, max; 
+               }
+       }'
+}
+
+function hwuiOutputParser {
+       # Stats since: 60659316905953ns
+       # Total frames rendered: 150
+       # Janky frames: 89 (59.33%)
+       # 90th percentile: 23ms
+       # 95th percentile: 27ms
+       # 99th percentile: 32ms
+       # Number Missed Vsync: 0
+       # Number High input latency: 0
+       # Number Slow UI thread: 0
+       # Number Slow bitmap uploads: 12
+       # Number Slow draw: 89
+       # use with "stdbuf -o0 " to disable pipe buffering
+       # stdbuf -o0 adb shell /data/hwuitest shadowgrid2 400 | stdbuf -o0 ./hwuitestfilter.sh  | tee t.csv
+       sed -e 's/ns//' -e 's/[\(\)%]/ /g' | awk '
+       BEGIN { startTime=0; lastTime=0; }
+       /^Stats since:/ {
+               curTime = $3;
+               if (startTime == 0) {
+                       startTime = curTime;
+               }
+               if (lastTime) {
+                       interval = curTime - lastTime;
+                       fps = totalFrames*1000000000 / interval;
+                       diffTime = curTime - startTime;
+                       printf "%.2f, %.2f, ",diffTime/1000000, fps;
+               }
+       }
+       /^Total frames/ { totalFrames=$4; }
+       /^Janky frames:/ {
+               if (lastTime) {
+                       printf "%.2f\n",$4; lastTime=curTime;
+               }
+               lastTime = curTime;
+       }'
+}
+
+function sysappOutputParser {
+       awk '
+       BEGIN { fmt=0; count=0; sum=0; }
+       /^App/ {
+               if (count != 0) {
+                       if (fmt > 2) printf "Ave: %0.2fms\n", sum/count;
+                       else printf " %0.2f\n", sum/count;
+                       count = 0;
+                       sum = 0;
+               }
+       }
+       /^[a-z]/ { val=$2; if (val != 0) { count++; sum+=val; } }
+       /^Iteration/ { if (fmt > 2) printf "%s : ", $0; else if (fmt) printf "%d ", $2; }
+       '
+}
+
+function calcPerfData {
+       testdir=$1
+       workload=$2
+       baselineCurrent=$3
+       baselinePower=$4
+
+       file=${workload}.out
+       powerfile=${workload}-power.out
+       build="$(cat build 2>/dev/null)"
+       build=${build:="Unknown"}
+
+       lines=$(wc -l $file 2>/dev/null | cut -f1 -d\ )
+
+       if [ ${lines:=0} -eq -0 ]; then
+               # No performance data captured
+               if [ "$format" = csv ]; then
+                       printf "%s,%s,%s\n" $testdir "$build" "no data"
+               else
+                       printf "%-30s %-8s %12.12s\n" $testdir "$build" "no data"
+               fi
+               return 1
+       fi
+
+       set -- $($POWERAVE $hz $voltage $powerfile)
+       current=$(echo $1 $baselineCurrent | awk '{ printf "%.2f", $1-$2; }')
+       power=$(echo $2 $baselinePower | awk '{ printf "%.2f", $1-$2; }')
+
+       case $workload in
+       (idle)
+               set -- 0 0 0
+               ;;
+       (suntemple)
+               # units are fps
+               set -- $(grep "FPS average" $file  | sed 's/^.*seconds for a //' | awk '{ print $1; }' | average)
+               ;;
+       (recentfling|youtube|chrome)
+               # units are ms, so need to convert to app/ms
+               set -- $(grep ^Frames:  $file | tr "/" " " | awk '{ print $4; }' | average | awk '{ printf "%.3f %.3f %.3f\n", 1000/$3, 1000/$2, 1000/$1;}'  )
+               ;;
+       (sysapps)
+               # units are ms, so need to convert to app/ms
+               set -- $(cat $file | sysappOutputParser | average | awk '{ printf "%.3f %.3f %.3f\n", 1000/$3, 1000/$2, 1000/$1;}'  )
+               ;;
+       (shadowgrid2)
+               # units are fps
+               set -- $(cat $file | hwuiOutputParser | tr ',' ' ' | awk '{print $2;}' | average)
+               ;;
+       esac
+
+       minperf=$1
+       aveperf=$2
+       maxperf=$3
+       perfPerWatt=$(echo $aveperf $power | awk '{ if ($2) { val=$1*1000/$2; printf "%.3f\n", val; } else print "unknown"; }')
+       if [ "$format" = csv ]; then
+               printf "%s,%s,%f,%f,%f,%f,%f,%f," $testdir "$build" $minperf $aveperf $maxperf $current $baselinePower $power
+               printf "%s\n" $perfPerWatt
+       else
+               printf "%-30s %-8s %12.2f %12.2f %12.2f %12.2f %12.2f %12.2f " $testdir "$build" $minperf $aveperf $maxperf $current $baselinePower $power
+               printf "%12s\n" $perfPerWatt
+       fi
+}
+
+function calcBaselinePower {
+       workload=$1
+       defaultPowerFile="idle-display-power.out"
+       powerFile=$defaultPowerFile
+       case $workload in
+       (shadowgrid2|suntemple|recentfling)
+               powerFile="idle-airplane-display-power.out"
+               if [ ! -f  $powerFile ]; then
+                       powerFile=$defaultPowerFile
+               fi;;
+       esac
+       if [ -f  $powerFile ]; then
+               $POWERAVE 5 4.3 $powerFile
+       fi
+}
+
+for t in $(cat tests)
+do
+       echo .======================= $t ================================
+       printHeader $t
+       for i in $testResults
+       do
+               cd $i
+               baseline="$(calcBaselinePower $t)"
+               if [ "$baseline" != "" ]; then
+                       calcPerfData $i $t $baseline
+               else
+                       echo "$i : no baseline current"
+               fi
+               cd - > /dev/null
+       done
+done
diff --git a/tests/workloads/pwrtest.sh b/tests/workloads/pwrtest.sh
new file mode 100755 (executable)
index 0000000..ca0f78d
--- /dev/null
@@ -0,0 +1,362 @@
+# Script to gather perf and perf/watt data for several workloads
+#
+# Setup:
+#
+# - device connected to monsoon with USB passthrough enabled
+# - network enabled (baseline will be measured and subtracted
+#   from results) (network needed for chrome, youtube tests)
+# - the device is rebooted after each test (can be inhibited
+#   with "-r 0")
+#
+# Default behavior is to run each of the known workloads for
+# 30 minutes gathering both performance and power data.
+#
+# The default time can be overridden with the -t option. To
+# change individual test times, a config file can be specifed
+# via -f with times for individual tests. Example file contents:
+#
+#      idleTime=60
+#      recentflingTime=60
+#      chromeTime=60
+#      youtubeTime=0
+#      sysappsTime=60
+#      suntempleTime=5
+#
+# Output goes to the current directory.
+#
+# Examples:
+#
+# - Run all tests for 15 minutes (default is 30): ./pwrtest.sh -t 15 -R MDA20
+#
+# - Use a config file for test times: ./pwrtest.sh -f ./myconfig -R MDA20
+#
+# - Use a init file to setup device tuneables after each restart (this is
+#   a bash script which should include adb commands to set up device):
+#     ./pwrtest.sh -F devtunables
+#
+defaultTime=30
+garbageminutes=8
+
+function Usage {
+       echo "Usage: $0 [OPTIONS]"
+       echo "-d device : device type (shamu, bullhead, ...)"
+       echo "-f configFile : config file to override individual test times"
+       echo "-g garbageMinutes : time to skip power measurement at beginning of test"
+       echo "                    default=$garbagetime minutes"
+       echo "-r restart : 0=no reboot between tests, 1=reboot (default)"
+       echo "-t defaultTimeMin : default time to run each test"
+       echo "                    default=$defaultTime minutes"
+       echo "-D cmddir : directory to find defs.sh"
+       echo "-F restartHookFile : file of commands to set device tunables after restart (optional)"
+       echo "-R release : release running on device (MDA20, 2054728, etc)"
+}
+
+restart=1
+hz=5
+shadowgrid2TimeMax=25
+
+CMDDIR=$(dirname $0 2>/dev/null)
+CMDDIR=${CMDDIR:=.}
+
+MONSOON=monsoon.par
+
+while [ $# -gt 0 ]
+do
+       case "$1" in
+       (-D) CMDDIR=$2; shift;;
+       (-r) restart=$2; shift;;
+       (-t) defaultTime=$2; shift;;
+       (-F) restartfile=$2; shift;;
+       (-g) garbageminutes=$2; shift;;
+       (-f)
+               configFile=$2;
+               echo "Reading configs from $configFile..."
+               . ./$configFile
+               shift;;
+       (-R) echo $2 > ./build; shift;;
+       (--) ;;
+       (--help)
+               Usage
+               exit 0;;
+       (*)
+               echo "Unknown option: $1"
+               Usage
+               exit 1;;
+       esac
+       shift
+done
+
+. $CMDDIR/defs.sh --
+
+devdir="/data/local/tmp"
+suntempledir=${CMDDIR}/suntemple
+
+case $DEVICE in
+(shamu|hammerhead)
+       HWUITEST=hwuitest
+       onSwipe="700 1847 700 400 50"
+       ;;
+(*)
+       HWUITEST=hwuitest64
+       onSwipe="500 1200 500 550 150"
+       ;;
+esac
+
+scripts="defs.sh systemapps.sh recentfling.sh youtube.sh chromefling.sh $HWUITEST"
+
+if ! $MONSOON >/dev/null 2>&1; then
+       echo $MONSOON must be in your PATH >&2
+       exit 1
+fi
+
+function usbpassthru {
+       if [ "$1" = off ]; then
+               state=off
+       else
+               state=on
+       fi
+       echo Setting usb pass-thru to $state
+       monsoon.par --usbpassthrough=$state
+}
+
+function pwrcollect {
+       collectmin=$1
+       collectmin=${collectmin:=60}
+       # samples = hz * 60 * minutes
+       ((samples=5*60*collectmin))
+       monsoon.par --timestamp --samples $samples --hz 5
+}
+
+function copy_files {
+       adb shell mkdir -p $devdir
+       for file in $scripts
+       do
+               adb push $CMDDIR/$file $devdir
+       done
+}
+
+function install_suntemple {
+       echo Checking for suntemple installation...
+       #stdest=/storage/sdcard0/obb/com.BrueComputing.SunTemple
+       stdest=/storage/emulated/0/obb/com.BrueComputing.SunTemple
+       dircontents=$(adb ls $stdest 2>/dev/null)
+       if [ "$dircontents" = "" ]; then
+               echo Installing suntemple...
+               adb install $suntempledir/*.apk
+               adb shell mkdir -p $stdest
+               adb push $suntempledir/main*obb $stdest
+       else
+               echo dircontents=$dircontents
+               echo Suntemple already installed.
+       fi
+}
+
+function run_test {
+       testName=$1
+       collectMinutes=$2
+       collectOutput=${testName}-power-raw.out
+       powerOutput=${testName}-power.out
+       echo -----------------------------------------------------
+       echo TEST: $testName
+       echo enabled Cores $(adb shell "cat /sys/devices/system/cpu/online")
+       date
+       echo -----------------------------------------------------
+       usbpassthru off
+       pwrcollect $collectMinutes > $collectOutput 2>/dev/null
+       # take off the first 2min of samples
+       totalSamples=$(cat $collectOutput | wc -l)
+       # we throw away the first "garbageminutes" of the data
+       # since it is volatile
+       ((garbage=hz*60*garbageminutes))
+       ((remaining=totalSamples-garbage))
+       if [ $remaining -gt 0 ]; then
+               tail -$remaining $collectOutput > $powerOutput
+       else
+               cp $collectOutput $powerOutput
+       fi
+       echo power data for $testName copied to $collectOutput
+       usbpassthru on
+       sleep 10
+       adb devices
+       sleep 10
+}
+
+function start_job {
+       cmdline="$1"
+       echo Running $cmdline
+       (adb shell "cd $devdir && nohup $cmdline > test.out") &
+       sleep 5
+       kill %1 2>/dev/null
+}
+
+function cleanup_job {
+       testName=$1
+       processName=$2
+       processName=${processName:=" sh "}
+       set -- $(adb shell ps | tr "\r" " " | grep "$processName")
+       echo killing PID=$2...
+       adb shell kill $2
+       sleep 1
+       echo copying test output to $testName...
+       adb pull $devdir/test.out
+       mv test.out ${testName}.out
+       if [ $restart -gt 0 ]; then
+               restart_device
+       else
+               doKeyevent HOME
+       fi
+}
+
+function airplane_mode {
+       if [ "$1" = "on" ]; then
+               mode=true
+               setting=1
+       else
+               mode=false
+               setting=0
+       fi
+       adb shell settings put global airplane_mode_on $setting
+       adb shell am broadcast -a android.intent.action.AIRPLANE_MODE --ez state $mode
+       echo Set airplane mode to $mode
+}
+
+function restart_device {
+       adb reboot
+       echo Wait 60s for device to restart...
+       sleep 60
+       while ! adb root
+       do
+               echo Waiting for device to come up...
+               sleep 10
+       done
+       echo Wait 30s to complete boot activities...
+       sleep 30
+       echo Restart complete.
+       doSwipe $onSwipe
+       restartfile=${restartfile:="./restarthook"}
+       if [ -f $restartfile ]; then
+               # hook to change tunables after a restart
+               . $restartfile
+       fi
+}
+
+usbpassthru on
+adb devices 2>/dev/null
+
+airplane_mode off
+if [ $restart -gt 0 ]; then
+       restart_device
+fi
+
+echo Copying $scripts to device $devdir...
+copy_files
+tests=""
+
+# measure background power
+idleTime=${idleTime:=$defaultTime}
+if [ $idleTime -gt 0 ]; then
+       echo Test 1 : measure idle power for $idleTime minutes
+       run_test idle $idleTime
+       airplane_mode on
+       echo Restarting for power baseline in airplane mode...
+       restart_device
+       run_test idle-airplane $idleTime
+       airplane_mode off
+       # the screen blanks after 30 minutes. The first 2 minutes of the test
+       # have already been filtered off. For our power baseline, keep the first
+       # 20 minutes of the results
+       ((twentyminutes=hz*20*60))
+       powerOutput="idle-power.out"
+       displayPowerOutput="idle-display-power.out"
+       airplanePowerOutput="idle-airplane-power.out"
+       airplaneDisplayPowerOutput="idle-airplane-display-power.out"
+       totalSamples=$(cat $powerOutput | wc -l)
+       if [ $twentyminutes -lt $totalSamples ]; then
+               head -$twentyminutes $powerOutput > $displayPowerOutput
+               head -$twentyminutes $airplanePowerOutput > $airplaneDisplayPowerOutput
+       else
+               cp $powerOutput $displayPowerOutput
+               cp $airplanePowerOutput $airplaneDisplayPowerOutput
+       fi
+       tests="$tests idle"
+fi
+
+recentflingTime=${recentflingTime:=$defaultTime}
+if [ $recentflingTime -gt 0 ]; then
+       echo $(date) Test 2 : recents fling for $recentflingTime minutes
+       airplane_mode on
+       adb shell "cd $devdir && ./systemapps.sh -A -T -i 1"
+       start_job "./recentfling.sh -N -i 1000 -d $DEVICE"
+       run_test recentfling $recentflingTime
+       cleanup_job recentfling
+       airplane_mode off
+       date
+       tests="$tests recentfling"
+fi
+
+suntempleTime=${suntempleTime:=$defaultTime}
+if [ $suntempleTime -gt 0 ]; then
+       echo $(date) Test 2 : run Sun Temple $suntempleTime minutes
+       airplane_mode on
+       install_suntemple
+       adb shell "am start $suntempleActivity"
+       run_test suntemple $suntempleTime
+       adb pull /sdcard/SunTemple/SunTemple/Saved/Logs/SunTemple.log
+       cleanup_job suntemple BrueComp
+       airplane_mode off
+       mv SunTemple.log suntemple.out
+       # grab the suntemple log
+       date
+       tests="$tests suntemple"
+fi
+
+chromeTime=${chromeTime:=$defaultTime}
+if [ $chromeTime -gt 0 ]; then
+       echo $(date) Test 3 : chrome fling for $chromeTime minutes
+       start_job "./chromefling.sh -i 1000 -d $DEVICE"
+       run_test chrome $chromeTime
+       cleanup_job chrome
+       date
+       tests="$tests chrome"
+fi
+
+shadowgrid2Time=${shadowgrid2Time:=$defaultTime}
+if [ $shadowgrid2Time -gt $shadowgrid2TimeMax ]; then
+       # we cap shadowgrid2 time since the display goes
+       # off after 30 minutes
+       $shadowgrid2Time=$shadowgrid2TimeMax
+fi
+if [ $shadowgrid2Time -gt 0 ]; then
+       airplane_mode on
+       echo $(date) Test 4 : shadowgrid2 for $shadowgrid2Time minutes
+       start_job "./$HWUITEST shadowgrid2 100000"
+       run_test shadowgrid2 $shadowgrid2Time
+       cleanup_job shadowgrid2 $HWUITEST
+       airplane_mode off
+       date
+       tests="$tests shadowgrid2"
+fi
+
+youtubeTime=${youtubeTime:=$defaultTime}
+if [ $youtubeTime -gt 0 ]; then
+       echo $(date) Test 5 : youtube for $youtubeTime minutes
+       start_job "./youtube.sh -i 1000 -d $DEVICE"
+       run_test youtube $youtubeTime
+       cleanup_job youtube
+       date
+       tests="$tests youtube"
+fi
+
+sysappsTime=${sysappsTime:=$defaultTime}
+if [ $sysappsTime -gt 0 ]; then
+       echo $(date) Test 6 : app switching for $sysappsTime minutes
+       start_job "./systemapps.sh -T -i 1000 -d $DEVICE"
+       run_test sysapps $sysappsTime
+       cleanup_job sysapps
+       date
+       tests="$tests sysapps"
+fi
+
+echo Ran tests: $tests
+echo $tests > tests
+
index 092c8d9..d495934 100755 (executable)
@@ -44,6 +44,12 @@ case $DEVICE in
        upCount=6
        UP="70 400 70 100 $flingtime"
        DOWN="70 100 70 400 $flingtime";;
+(angler)
+       flingtime=150
+       downCount=4
+       upCount=3
+       UP="500 1200 500 550 $flingtime"
+       DOWN="500 550 500 1200 $flingtime";;
 (bullhead)
        flingtime=200
        downCount=5
@@ -122,7 +128,6 @@ do
        latency99=$5
        if [ ${totalDiff:=0} -eq 0 ]; then
                echo Error: could not read frame info with \"dumpsys gfxinfo\"
-               exit 1
        fi
 
        ((frameSum=frameSum+totalDiff))
@@ -132,7 +137,6 @@ do
        ((latency99Sum=latency99Sum+latency99))
        if [ "$totalDiff" -eq 0 ]; then
                echo Error: no frames detected. Is the display off?
-               exit 1
        fi
        ((jankPct=jankyDiff*100/totalDiff))
        resetJankyFrames
index a263e7d..6c0db35 100755 (executable)
 # Other options are described below.
 #
 iterations=1
-tracecategories="gfx view am input memreclaim"
+tracecategories="gfx am memreclaim"
 totaltimetest=0
 forcecoldstart=0
 waitTime=3.0
+memstats=0
 
-appList="gmail hangouts chrome youtube play home"
+appList="gmail maps chrome youtube play home"
 
 function processLocalOption {
        ret=0
@@ -38,6 +39,7 @@ function processLocalOption {
        (-L) appList=$2; shift; ret=1;;
        (-T) totaltimetest=1;;
        (-W) waitTime=$2; shift; ret=1;;
+       (-M) memstats=1;;
        (*)
                echo "$0: unrecognized option: $1"
                echo; echo "Usage: $0 [options]"
@@ -141,6 +143,7 @@ do
        if [ $iterations -gt 1 ]; then
                echo =========================================
                echo Iteration $cur of $iterations
+               date
                echo =========================================
        fi
        if [ $iterations -gt 1 -o $cur -eq 1 ]; then
@@ -160,8 +163,11 @@ do
                if [ $totaltimetest -eq 0 ]; then
                        tmpTraceOut="$tmpTraceOutBase-$app.out"
                        >$tmpTraceOut
-                       startInstramentation
+                       startInstramentation "$app-$cur"
                else
+                       if [ "$memstats" -gt 0 ]; then
+                               startInstramentation "$app-$cur" 0
+                       fi
                        if [ $appnum -eq 0 ]; then
                                printf "%-8s %5s(ms) %3s(ms) %s      %s\n" App Start Iter Jank Latency
                        fi
@@ -239,6 +245,8 @@ if [ $totaltimetest -gt 0 ]; then
        printf "%-10s %5.0f   %5.0f\n" TOTAL $totaltime $diffTime
 fi
 
+overallSum=0
+appCount=0
 if [ $iterations -gt 1 -a $totaltimetest -eq 0 ]; then
        echo
        echo =========================================
@@ -258,7 +266,14 @@ if [ $iterations -gt 1 -a $totaltimetest -eq 0 ]; then
                ((ave90=l90/iterations))
                ((ave95=l95/iterations))
                ((ave99=l99/iterations))
-               ((jankPct=100*janks/frames))
+               if [ $frames -gt 0 ]; then
+                       ((jankPct=100*janks/frames))
+               fi
                printf "%-12s %5d      %5d      %5d      %5d      %5d     %5d(%d%%) %d/%d/%d\n" $app $1 $ave $2 $4 $5 $janks $jankPct $ave90 $ave95 $ave99
+               ((overallSum=overallSum+ave))
+               ((appCount=appCount+1))
        done
+       if [ $appCount -gt 0 ]; then
+               printf "Average Start Time: %.2f\n", $(echo $overallSum $appCount | awk '{ printf "%.2f\n", $1/$2 }')
+       fi
 fi
diff --git a/tests/workloads/youtube.sh b/tests/workloads/youtube.sh
new file mode 100755 (executable)
index 0000000..2d6b136
--- /dev/null
@@ -0,0 +1,139 @@
+#
+# Script to play a john oliver youtube video N times.
+# For each iteration, Total frames and janky frames are reported.
+#
+# Options are described below.
+#
+iterations=10
+app=youtube
+searchText="last week tonight with john oliver: online harassment"
+
+function processLocalOption {
+       ret=0
+       case "$1" in
+       (-S) searchText="$2"; shift;;
+       (*)
+               echo "$0: unrecognized option: $1"
+               echo; echo "Usage: $0 [options]"
+               echo "-i iterations"
+               echo "-S youtube search text"
+               echo "-d device"
+               exit 1;;
+       esac
+       return $ret
+}
+
+CMDDIR=$(dirname $0 2>/dev/null)
+CMDDIR=${CMDDIR:=.}
+. $CMDDIR/defs.sh
+
+case $DEVICE in
+(angler)
+       searchButton="860 177"
+       selectFirstVideo="225 400"
+       enableControls="1000 610"
+       fullScreen="1011 632"
+       ;;
+(shamu)
+       searchButton="1200 160"
+       selectFirstVideo="480 653"
+       enableControls="1377 812"
+       fullScreen="1377 812"
+       ;;
+(bullhead|hammerhead)
+       searchButton="860 177"
+       selectFirstVideo="225 400"
+       enableControls="1000 610"
+       fullScreen="1011 632"
+       ;;
+(volantis)
+       searchButton="1356 93"
+       selectFirstVideo="378 264"
+       enableControls="1464 812"
+       fullScreen="1480 835"
+       ;;
+(*)
+       echo "Error: No display information available for $DEVICE"
+       exit 1;;
+esac
+
+function swipe {
+       count=0
+       while [ $count -lt $2 ]
+       do
+               echo doSwipe...
+               doSwipe $1
+               ((count=count+1))
+       done
+       sleep 1
+}
+
+cur=1
+frameSum=0
+jankSum=0
+latency90Sum=0
+latency95Sum=0
+latency99Sum=0
+
+doKeyevent HOME
+sleep 0.5
+resetJankyFrames $(getPackageName $app)
+
+while [ $cur -le $iterations ]
+do
+       t=$(startActivity $app)
+       sleep 4.0
+       doTap $searchButton
+       sleep 1.0
+       doText "$searchText"
+       sleep 1.0
+       doKeyevent ENTER
+       sleep 5.0
+       doTap $selectFirstVideo
+       sleep 10.0
+       doTap $fullScreen
+       sleep 0.5
+       doTap $fullScreen
+       # 15 minutes
+       ((vidTime=60*15))
+       sleep $vidTime
+       doKeyevent BACK
+       sleep 0.5
+       doKeyevent BACK
+       sleep 0.5
+       doKeyevent BACK
+       sleep 0.5
+
+       set -- $(getJankyFrames $(getPackageName $app))
+       totalDiff=$1
+       jankyDiff=$2
+       latency90=$3
+       latency95=$4
+       latency99=$5
+       if [ ${totalDiff:=0} -eq 0 ]; then
+               echo Error: could not read frame info with \"dumpsys gfxinfo\"
+       fi
+
+       ((frameSum=frameSum+totalDiff))
+       ((jankSum=jankSum+jankyDiff))
+       ((latency90Sum=latency90Sum+latency90))
+       ((latency95Sum=latency95Sum+latency95))
+       ((latency99Sum=latency99Sum+latency99))
+       if [ "$totalDiff" -eq 0 ]; then
+               echo Error: no frames detected. Is the display off?
+       fi
+       ((jankPct=jankyDiff*100/totalDiff))
+       resetJankyFrames $(getPackageName $app)
+
+
+       echo Frames: $totalDiff latency: $latency90/$latency95/$latency99 Janks: $jankyDiff\(${jankPct}%\)
+       ((cur=cur+1))
+done
+doKeyevent HOME
+((aveJankPct=jankSum*100/frameSum))
+((aveJanks=jankSum/iterations))
+((aveFrames=frameSum/iterations))
+((aveLatency90=latency90Sum/iterations))
+((aveLatency95=latency95Sum/iterations))
+((aveLatency99=latency99Sum/iterations))
+echo AVE: Frames: $aveFrames latency: $aveLatency90/$aveLatency95/$aveLatency99 Janks: $aveJanks\(${aveJankPct}%\)