1#!/bin/sh 2 3parseoptions() { 4 verbose=false 5 user_experience=false 6 little_cores_off=false 7 iterations=0 8 pagecached=false 9 10 while [ $# -gt 1 ] 11 do 12 case $1 in 13 -a) 14 ;; 15 -b) 16 little_cores_off=true 17 ;; 18 -c) 19 pagecached=true 20 ;; 21 -h) 22 usage 23 ;; 24 -u) 25 user_experience=true 26 ;; 27 -v) 28 verbose=true 29 ;; 30 *) 31 usage 32 ;; 33 esac 34 shift 35 done 36 37 iterations=$1 38 if [ $iterations -lt 100 ]; then 39 usage 40 fi 41} 42 43getstats () { 44 infile=$1 45 app=$2 46 echo "Data for $app :" 47 48 # Activity Manager reports ThisTime and TotalTime. TotalTime seems to be 49 # a more measure of the launch from the users perspective. So using TotalTime 50 # as our metric for launch latency 51 52 # From Activity Manager 53 echo "Launch Time (TotalTime) :" 54 fgrep TotalTime $infile | awk '{print $2}' | computestats 55 56 # Data from simpleperf 57 echo "cpu-cycles :" 58 fgrep cpu-cycles $infile | awk '{print $1}' | sed s/,//g | computestats 59 60 # CPU util% Data from /proc/stat 61 echo "cpu-util% :" 62 fgrep 'Total CPU util' $infile | awk '{print $5}' | computestatsf 63 echo "user-cpu-util% :" 64 fgrep 'User CPU util' $infile | awk '{print $5}' | computestatsf 65 echo "sys-cpu-util% (incl hardirq/softirq) :" 66 fgrep 'Sys CPU util' $infile | awk '{print $5}' | computestatsf 67 68 if [ $verbose == true ]; then 69 echo "instructions : " 70 fgrep instructions $infile | awk '{print $1}' | sed s/,//g | computestats 71 72 echo "cycles per instruction : " 73 fgrep instructions $infile | awk '{print $4}' | sed s/,//g | computestatsf 74 75 echo "branch-misses : " 76 fgrep branch-misses $infile | awk '{print $1}' | sed s/,//g | computestats 77 78 echo "context-switches : " 79 fgrep context-switches $infile | awk '{print $1}' | sed s/,//g | computestats 80 81 echo "page-faults : " 82 fgrep page-faults $infile | awk '{print $1}' | sed s/,//g | computestats 83 fi 84 85 if [ $system_bdev_set == true ]; then 86 # (Storage) Data from /proc we've collected 87 echo "KB read for $system_block_device blkdev :" 88 fgrep KB $infile | grep system | awk '{print $5}' | computestats 89 90 echo "iowait% :" 91 fgrep IOwait $infile | awk '{print $3}' | computestatsf 92 93 echo "Device util% for $system_block_device blkdev :" 94 fgrep 'Device util' $infile | awk '{print $4}' | computestatsf 95 fi 96} 97 98cpufreq_volantis() { 99 echo "Setting Governor to performance" 100 if [ $little_cores_off == true ]; then 101 echo "Cannot turn off Little cores on $model" 102 exit 1 103 fi 104 i=0 105 num_cores=2 106 while [ $i -lt $num_cores ] 107 do 108 adb shell "echo performance > /sys/devices/system/cpu/cpu$i/cpufreq/scaling_g\ 109overnor" 110 adb shell "echo 2499000 > /sys/devices/system/cpu/cpu$i/cpufreq/scaling_max_fr\ 111eq" 112 i=`expr $i + 1` 113 done 114 # Lock the GPU frequencies 115 echo -n 852000000 > /d/clock/override.gbus/rate 116 echo -n 1 > /d/clock/override.gbus/state 117} 118 119cpufreq_fugu() { 120 echo "Setting Governor to performance" 121 if [ $little_cores_off == true ]; then 122 echo "Cannot turn off Little cores on $model" 123 exit 1 124 fi 125 i=0 126 num_cores=4 127 while [ $i -lt $num_cores ] 128 do 129 adb shell "echo performance > /sys/devices/system/cpu/cpu$i/cpufreq/scaling_governor" 130 adb shell "echo 1833000 > /sys/devices/system/cpu/cpu$i/cpufreq/scaling_max_freq" 131 i=`expr $i + 1` 132 done 133} 134 135cpufreq_marlin_sailfish () { 136 echo "Setting Governor to performance" 137 # GPU Governor and Frequency 138 adb shell 'echo performance > /sys/class/kgsl/kgsl-3d0/devfreq/governor' 139 adb shell 'echo 624000000 > /sys/class/kgsl/kgsl-3d0/devfreq/max_freq' 140 if [ $little_cores_off == true ]; then 141 # Disable Little Cores, force app to run on big cores 142 echo "Disabling Little Cores" 143 adb shell 'echo 0 > /sys/devices/system/cpu/cpu0/online' 144 adb shell 'echo 0 > /sys/devices/system/cpu/cpu1/online' 145 else 146 echo "Enabling All Cores" 147 adb shell 'echo 1 > /sys/devices/system/cpu/cpu0/online' 148 adb shell 'echo 1 > /sys/devices/system/cpu/cpu1/online' 149 adb shell 'echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor' 150 adb shell 'echo 1996800 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq' 151 # cpu1 needed ? 152 adb shell 'echo performance > /sys/devices/system/cpu/cpu1/cpufreq/scaling_governor' 153 adb shell 'echo 1996800 > /sys/devices/system/cpu/cpu1/cpufreq/scaling_max_freq' 154 fi 155 # Set Governor to performance, up scaling_max_frequency to highest 156 adb shell 'echo performance > /sys/devices/system/cpu/cpu2/cpufreq/scaling_governor' 157 # Only necessary to set max_freq on cpu2, cpu3 is in same cluster and will 158 # automatically get the same settings 159 adb shell 'echo 2150400 > /sys/devices/system/cpu/cpu2/cpufreq/scaling_max_freq' 160} 161 162cpufreq_angler () { 163 echo "Setting Governor and Frequency" 164 # GPU Governor and Frequency 165 adb shell "echo performance > /sys/class/kgsl/kgsl-3d0/devfreq/governor" 166 adb shell "echo 0 > /sys/class/kgsl/kgsl-3d0/bus_split" 167 adb shell "echo 1 > /sys/class/kgsl/kgsl-3d0/force_clk_on" 168 adb shell "echo 10000 > /sys/class/kgsl/kgsl-3d0/idle_timer" 169 if [ $little_cores_off == true ]; then 170 # Disable Little Cores, force app to run on big cores 171 echo "Disabling Little Cores" 172 i=0 173 num_cores=4 174 while [ $i -lt $num_cores ] 175 do 176 adb shell "echo 0 > /sys/devices/system/cpu/cpu$i/online" 177 i=`expr $i + 1` 178 done 179 else 180 echo "Enabling All Cores" 181 # Enable Little cores here, set governor to performance 182 # Lock frequency of little cores 183 i=0 184 num_cores=4 185 while [ $i -lt $num_cores ] 186 do 187 adb shell "echo 1 > /sys/devices/system/cpu/cpu$i/online" 188 adb shell "echo performance > /sys/devices/system/cpu/cpu$i/cpufreq/scaling_governor" 189 # Lock frequency of little cores 190 adb shell "echo 1555200 > /sys/devices/system/cpu/cpu$i/cpufreq/scaling_max_freq" 191 i=`expr $i + 1` 192 done 193 fi 194 i=4 195 num_cores=8 196 while [ $i -lt $num_cores ] 197 do 198 adb shell "echo performance > /sys/devices/system/cpu/cpu$i/cpufreq/scaling_governor" 199 # Lock frequency of big cores 200 adb shell "echo 1958400 > /sys/devices/system/cpu/cpu$i/cpufreq/scaling_max_freq" 201 i=`expr $i + 1` 202 done 203} 204 205# 206# This strange bit of logic is needed to get the underlying block devices for /system 207# for Marlin/Sailfish 208# 209get_marlin_sailfish_devnames () { 210 # This bit of code required to get the block dev for /system and /vendor 211 # Suffix can be _a or _b, depending on what the active /system partition is 212# suffix=`adb shell getprop ro.boot.slot_suffix` 213 # Get the blockdevice using the suffix we got above 214# system_block_device=`adb shell ls -l /dev/block/platform/soc/*ufs*/by-name/system$suffix | awk '{ print $10 }' ` 215 # Vendor is more straightforward, but we don't use it right now 216# vendor_block_device=`adb shell df /vendor | grep -v Filesystem | awk '{print $1}' ` 217 # finally extract the last component of the absolute device pathname we got above 218# system_block_device=`echo $system_block_device | awk 'BEGIN { FS ="/" } ; { print $4 }' ` 219# vendor_block_device=`echo $vendor_block_device | awk 'BEGIN { FS ="/" } ; { print $4 }' ` 220 system_bdev_set=true 221# For now, hardcode sda for Marlin/Sailfish block device 222# XXX - We'll get stats for entire device 223 system_block_device=sda 224 echo Block Device $system_block_device 225} 226 227get_angler_devnames () { 228 # Get the underlying bdev from the "by-name" mapping 229 system_block_device=`adb shell 'find /dev/block/platform -name by-name | xargs ls -l' | grep system | awk '{ print $10 }' ` 230 # extract the last component of the absolute device pathname we got above 231 system_block_device=`echo $system_block_device | awk 'BEGIN { FS ="/" } ; { print $4 }' ` 232 # vendor is unused right now, but get the bdev anyway in case we decide to use it 233 # Get the underlying bdev from the "by-name" mapping 234 vendor_block_device=`adb shell 'find /dev/block/platform -name by-name | xargs ls -l' | grep vendor | awk '{ print $10 }' ` 235 # extract the last component of the absolute device pathname we got above 236 vendor_block_device=`echo $vendor_block_device | awk 'BEGIN { FS ="/" } ; { print $4 }' ` 237 system_bdev_set=true 238} 239 240get_fugu_devnames () { 241 system_block_device=`adb shell ls -l /dev/block/by-name/system | awk '{ print $10 }' ` 242 system_block_device=`echo $system_block_device | awk 'BEGIN { FS ="/" } ; { print $4 }' ` 243 system_bdev_set=true 244} 245 246get_volantis_devnames () { 247 # Hardcoding all of the mmcblk0 device for now 248 system_block_device=mmcblk0 249 system_bdev_set=true 250} 251 252system_stats_before() { 253 if [ $system_bdev_set == true ]; then 254 # Get BEFORE read stats for /system 255 adb shell 'cat /proc/diskstats' | grep -w $system_block_device > /tmp/$model-system 256 BEFORE_RD_IOS_SYSTEM=`awk '{ print $4 }' /tmp/$model-system` 257 BEFORE_RD_SECTORS_SYSTEM=`awk '{ print $6 }' /tmp/$model-system` 258 # iowait% computation 259 adb shell 'cat /proc/stat' | grep -w cpu > /tmp/procstat 260 user_ticks_before=`awk '{ print ($2 + $3) }' /tmp/procstat` 261 sys_ticks_before=`awk '{ print ($4 + $7 + $8) }' /tmp/procstat` 262 cpubusy_ticks_before=`awk '{ print ($2 + $3 + $4 + $7 + $8) }' /tmp/procstat` 263 iowait_ticks_before=`awk '{ print $6 }' /tmp/procstat` 264 total_ticks_before=`awk '{ print ($2 + $3 + $4 + $5 + $7 + $8) }' /tmp/procstat` 265 # Device util% computation 266 # Note hz=100, so multiplying uptime (in seconds) by 100, gives us 267 # the uptime in hz. 268 adb shell 'cat /proc/uptime' > /tmp/uptime 269 uptime_before_hz=`awk '{ print ($1 * 100) }' /tmp/uptime` 270 # Note that the device (busy) ticks is in ms. Since hz=100, dividing 271 # device (busy) ticks by 10, gives us this in the correct ticks units 272 device_util_before_hz=`awk '{ print ($13 / 10) }' /tmp/$model-system` 273 fi 274} 275 276system_stats_after() { 277 if [ $system_bdev_set == true ]; then 278 # Get AFTER read stats for /system 279 adb shell 'cat /proc/diskstats' | grep -w $system_block_device > /tmp/$model-system 280 AFTER_RD_IOS_SYSTEM=`awk '{ print $4 }' /tmp/$model-system` 281 AFTER_RD_SECTORS_SYSTEM=`awk '{ print $6 }' /tmp/$model-system` 282 # iowait% computation 283 adb shell 'cat /proc/stat' | grep -w cpu > /tmp/procstat 284 user_ticks_after=`awk '{ print ($2 + $3) }' /tmp/procstat` 285 sys_ticks_after=`awk '{ print ($4 + $7 + $8) }' /tmp/procstat` 286 cpubusy_ticks_after=`awk '{ print ($2 + $3 + $4 + $7 + $8) }' /tmp/procstat` 287 iowait_ticks_after=`awk '{ print $6 }' /tmp/procstat` 288 total_ticks_after=`awk '{ print ($2 + $3 + $4 + $5 + $7 + $8) }' /tmp/procstat` 289 # Device util% computation 290 # Note hz=100, so multiplying uptime (in seconds) by 100, gives us 291 # the uptime in hz. 292 adb shell 'cat /proc/uptime' > /tmp/uptime 293 uptime_after_hz=`awk '{ print ($1 * 100) }' /tmp/uptime` 294 # Note that the device (busy) ticks is in ms. Since hz=100, dividing 295 # device (busy) ticks by 10, gives us this in the correct ticks units 296 device_util_after_hz=`awk '{ print ($13 / 10) }' /tmp/$model-system` 297 fi 298} 299 300system_stats_delta() { 301 if [ $system_bdev_set == true ]; then 302 # Sectors to KB 303 READ_KB_SYSTEM=`expr $AFTER_RD_SECTORS_SYSTEM - $BEFORE_RD_SECTORS_SYSTEM` 304 READ_KB_SYSTEM=`expr $READ_KB_SYSTEM / 2` 305 echo Read IOs /system = `expr $AFTER_RD_IOS_SYSTEM - $BEFORE_RD_IOS_SYSTEM` 306 echo Read KB /system = $READ_KB_SYSTEM 307 echo $iowait_ticks_before $iowait_ticks_after $total_ticks_before $total_ticks_after | awk '{ printf "IOwait = %.2f\n", (($2 - $1) * 100.0) / ($4 - $3) }' 308 echo $device_util_before_hz $device_util_after_hz $uptime_before_hz $uptime_after_hz | awk '{ printf "Device util% = %.2f\n", (($2 - $1) * 100.0) / ($4 - $3) }' 309 echo $user_ticks_after $user_ticks_before $total_ticks_after $total_ticks_before | awk '{ printf "User CPU util% = %.2f\n", (($1 - $2) * 100.0) / ($3 - $4) }' 310 echo $sys_ticks_after $sys_ticks_before $total_ticks_after $total_ticks_before | awk '{ printf "Sys CPU util% = %.2f\n", (($1 - $2) * 100.0) / ($3 - $4) }' 311 echo $cpubusy_ticks_after $cpubusy_ticks_before $total_ticks_after $total_ticks_before | awk '{ printf "Total CPU util% = %.2f\n", (($1 - $2) * 100.0) / ($3 - $4) }' 312 fi 313} 314 315launch_app() { 316 package=$1 317 activity=$2 318 adb shell "am force-stop $package" 319 sleep 1 320 321 i=0 322 while [ $i -lt $iterations ] 323 do 324 if [ $pagecached == false ]; then 325 adb shell 'echo 3 > /proc/sys/vm/drop_caches' 326 fi 327 # The -W argument to am start forces am start to wait till the launch completes. 328 # The -S argument forces it to kill any existing app that is running first 329 # eg. adb shell 'am start -W -S -n com.android.chrome/com.google.android.apps.chrome.Main' 330 system_stats_before 331 adb shell "simpleperf stat -a am start -W -n $package/$activity" 332 system_stats_after 333 system_stats_delta 334 sleep 1 335 adb shell "am force-stop $package" 336 sleep 1 337 i=`expr $i + 1` 338 done 339} 340 341launch_fugu_apps() { 342 launch_app com.google.android.youtube.tv com.google.android.apps.youtube.tv.activity.TvGuideActivity > youtube-$model 343 getstats youtube-$model YouTube 344 launch_app com.google.android.play.games com.google.android.gms.games.pano.activity.PanoGamesOnboardHostActivity > games-$model 345 getstats games-$model Games 346 launch_app com.google.android.music com.android.music.activitymanagement.TopLevelActivity > music-$model 347 getstats music-$model Music 348} 349 350launch_phone_apps() { 351 launch_app com.android.chrome com.google.android.apps.chrome.Main > chrome-$model 352 getstats chrome-$model Chrome 353 launch_app com.google.android.GoogleCamera com.android.camera.CameraActivity > camera-$model 354 getstats camera-$model Camera 355 launch_app com.google.android.apps.maps com.google.android.maps.MapsActivity > maps-$model 356 getstats maps-$model Maps 357 launch_app com.google.android.youtube com.google.android.apps.youtube.app.WatchWhileActivity > youtube-$model 358 getstats youtube-$model YouTube 359} 360 361usage() { 362 echo 'Usage: app-launcher [-c|-v] -a|-b|-u num-iterations' 363 echo 'where num-iterations >= 100' 364 echo '-v (optional) for verbose stats dump' 365 echo '-a|-b|-u required:' 366 echo ' -a:all cores' 367 echo ' -b:only big cores' 368 echo ' -c:pagecached. Do not drop pagecache before each launch (not default)' 369 echo ' -h:Dump this help menu' 370 echo ' -u:user experience, no change to cpu/gpu frequencies or governors' 371 echo ' -a/-b locks CPU/GPU freqs to max, performance governor, thermal/perfd off' 372 echo ' -u runs with default device configs, as users would see it' 373 exit 1 374} 375 376# 377# The main() part of the script follows : 378# 379 380if [ $# -lt 2 ]; then 381 usage 382fi 383 384which computestats > /dev/null 385if [ $? != 0 ]; then 386 echo "ERROR: Please add computestats utiliy to your PATH" 387 exit 1 388fi 389 390which computestatsf > /dev/null 391if [ $? != 0 ]; then 392 echo "Error: Please add computestatsf utility to your PATH" 393 exit 1 394fi 395 396parseoptions $@ 397 398adb root && sleep 2 399 400if [ $user_experience == false ]; then 401 # Important to stop the thermal-engine to prevent throttling while test is running 402 # and stop perfd 403 adb shell 'stop thermal-engine' 404 adb shell 'stop perfd' 405else 406 echo "User Experience: Default Configs. No changes to cpufreq settings" 407fi 408 409model=`adb shell getprop ro.product.name` 410# Releases are inconsistent with various trailing characters, remove them all 411model=`echo $model | sed 's/[ \t\r\n]*$//' ` 412 413echo Found $model Device 414 415system_bdev_set=false 416case $model in 417 marlin | sailfish) 418 if [ $user_experience == false ]; then 419 cpufreq_marlin_sailfish 420 fi 421 get_marlin_sailfish_devnames 422 ;; 423 angler) 424 if [ $user_experience == false ]; then 425 cpufreq_angler 426 fi 427 get_angler_devnames 428 ;; 429 fugu) 430 if [ $user_experience == false ]; then 431 cpufreq_fugu 432 fi 433 get_fugu_devnames 434 ;; 435 volantis | volantisg) 436 if [ $user_experience == false ]; then 437 cpufreq_volantis 438 fi 439 get_volantis_devnames 440 ;; 441 *) 442 echo Unknown Device $model 443 exit 1 444 ;; 445esac 446 447 448# 449# launch each app in turn 450# 451if [ $model == "fugu" ]; then 452 launch_fugu_apps 453else # Phone Apps 454 launch_phone_apps 455fi 456