1*d83cc019SAndroid Build Coastguard Worker#! /usr/bin/perl 2*d83cc019SAndroid Build Coastguard Worker# 3*d83cc019SAndroid Build Coastguard Worker# Copyright © 2017 Intel Corporation 4*d83cc019SAndroid Build Coastguard Worker# 5*d83cc019SAndroid Build Coastguard Worker# Permission is hereby granted, free of charge, to any person obtaining a 6*d83cc019SAndroid Build Coastguard Worker# copy of this software and associated documentation files (the "Software"), 7*d83cc019SAndroid Build Coastguard Worker# to deal in the Software without restriction, including without limitation 8*d83cc019SAndroid Build Coastguard Worker# the rights to use, copy, modify, merge, publish, distribute, sublicense, 9*d83cc019SAndroid Build Coastguard Worker# and/or sell copies of the Software, and to permit persons to whom the 10*d83cc019SAndroid Build Coastguard Worker# Software is furnished to do so, subject to the following conditions: 11*d83cc019SAndroid Build Coastguard Worker# 12*d83cc019SAndroid Build Coastguard Worker# The above copyright notice and this permission notice (including the next 13*d83cc019SAndroid Build Coastguard Worker# paragraph) shall be included in all copies or substantial portions of the 14*d83cc019SAndroid Build Coastguard Worker# Software. 15*d83cc019SAndroid Build Coastguard Worker# 16*d83cc019SAndroid Build Coastguard Worker# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17*d83cc019SAndroid Build Coastguard Worker# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18*d83cc019SAndroid Build Coastguard Worker# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19*d83cc019SAndroid Build Coastguard Worker# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20*d83cc019SAndroid Build Coastguard Worker# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21*d83cc019SAndroid Build Coastguard Worker# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22*d83cc019SAndroid Build Coastguard Worker# IN THE SOFTWARE. 23*d83cc019SAndroid Build Coastguard Worker# 24*d83cc019SAndroid Build Coastguard Worker 25*d83cc019SAndroid Build Coastguard Workeruse strict; 26*d83cc019SAndroid Build Coastguard Workeruse warnings; 27*d83cc019SAndroid Build Coastguard Workeruse 5.010; 28*d83cc019SAndroid Build Coastguard Worker 29*d83cc019SAndroid Build Coastguard Workeruse Getopt::Std; 30*d83cc019SAndroid Build Coastguard Worker 31*d83cc019SAndroid Build Coastguard Workerchomp(my $igt_root = `pwd -P`); 32*d83cc019SAndroid Build Coastguard Workermy $wsim = "$igt_root/benchmarks/gem_wsim"; 33*d83cc019SAndroid Build Coastguard Workermy $wrk_root = "$igt_root/benchmarks/wsim"; 34*d83cc019SAndroid Build Coastguard Workermy $tracepl = "$igt_root/scripts/trace.pl"; 35*d83cc019SAndroid Build Coastguard Workermy $tolerance = 0.01; 36*d83cc019SAndroid Build Coastguard Workermy $client_target_s = 10; 37*d83cc019SAndroid Build Coastguard Workermy $idle_tolerance_pct = 2.0; 38*d83cc019SAndroid Build Coastguard Workermy $verbose = 0; 39*d83cc019SAndroid Build Coastguard Workermy $gt2 = 0; 40*d83cc019SAndroid Build Coastguard Workermy $show_cmds = 0; 41*d83cc019SAndroid Build Coastguard Workermy $realtime_target = 0; 42*d83cc019SAndroid Build Coastguard Workermy $wps_target = 0; 43*d83cc019SAndroid Build Coastguard Workermy $wps_target_param = 0; 44*d83cc019SAndroid Build Coastguard Workermy $multi_mode = 0; 45*d83cc019SAndroid Build Coastguard Workermy @multi_workloads; 46*d83cc019SAndroid Build Coastguard Workermy $w_direct; 47*d83cc019SAndroid Build Coastguard Workermy $balancer; 48*d83cc019SAndroid Build Coastguard Workermy $nop; 49*d83cc019SAndroid Build Coastguard Workermy %opts; 50*d83cc019SAndroid Build Coastguard Worker 51*d83cc019SAndroid Build Coastguard Workermy @balancers = ( 'rr', 'rand', 'qd', 'qdr', 'qdavg', 'rt', 'rtr', 'rtavg', 52*d83cc019SAndroid Build Coastguard Worker 'context', 'busy', 'busy-avg', 'i915' ); 53*d83cc019SAndroid Build Coastguard Workermy %bal_skip_H = ( 'rr' => 1, 'rand' => 1, 'context' => 1, , 'busy' => 1, 54*d83cc019SAndroid Build Coastguard Worker 'busy-avg' => 1, 'i915' => 1 ); 55*d83cc019SAndroid Build Coastguard Workermy %bal_skip_R = ( 'i915' => 1 ); 56*d83cc019SAndroid Build Coastguard Workermy %bal_skip_G = ( 'i915' => 1 ); 57*d83cc019SAndroid Build Coastguard Worker 58*d83cc019SAndroid Build Coastguard Workermy @workloads = ( 59*d83cc019SAndroid Build Coastguard Worker 'media_load_balance_17i7.wsim', 60*d83cc019SAndroid Build Coastguard Worker 'media_load_balance_19.wsim', 61*d83cc019SAndroid Build Coastguard Worker 'media_load_balance_4k12u7.wsim', 62*d83cc019SAndroid Build Coastguard Worker 'media_load_balance_fhd26u7.wsim', 63*d83cc019SAndroid Build Coastguard Worker 'media_load_balance_hd01.wsim', 64*d83cc019SAndroid Build Coastguard Worker 'media_load_balance_hd06mp2.wsim', 65*d83cc019SAndroid Build Coastguard Worker 'media_load_balance_hd12.wsim', 66*d83cc019SAndroid Build Coastguard Worker 'media_load_balance_hd17i4.wsim', 67*d83cc019SAndroid Build Coastguard Worker 'media_1n2_480p.wsim', 68*d83cc019SAndroid Build Coastguard Worker 'media_1n3_480p.wsim', 69*d83cc019SAndroid Build Coastguard Worker 'media_1n4_480p.wsim', 70*d83cc019SAndroid Build Coastguard Worker 'media_1n5_480p.wsim', 71*d83cc019SAndroid Build Coastguard Worker 'media_1n2_asy.wsim', 72*d83cc019SAndroid Build Coastguard Worker 'media_1n3_asy.wsim', 73*d83cc019SAndroid Build Coastguard Worker 'media_1n4_asy.wsim', 74*d83cc019SAndroid Build Coastguard Worker 'media_1n5_asy.wsim', 75*d83cc019SAndroid Build Coastguard Worker 'media_mfe2_480p.wsim', 76*d83cc019SAndroid Build Coastguard Worker 'media_mfe3_480p.wsim', 77*d83cc019SAndroid Build Coastguard Worker 'media_mfe4_480p.wsim', 78*d83cc019SAndroid Build Coastguard Worker 'media_nn_1080p.wsim', 79*d83cc019SAndroid Build Coastguard Worker 'media_nn_480p.wsim', 80*d83cc019SAndroid Build Coastguard Worker ); 81*d83cc019SAndroid Build Coastguard Worker 82*d83cc019SAndroid Build Coastguard Workersub show_cmd 83*d83cc019SAndroid Build Coastguard Worker{ 84*d83cc019SAndroid Build Coastguard Worker my ($cmd) = @_; 85*d83cc019SAndroid Build Coastguard Worker 86*d83cc019SAndroid Build Coastguard Worker say "\n+++ $cmd" if $show_cmds; 87*d83cc019SAndroid Build Coastguard Worker} 88*d83cc019SAndroid Build Coastguard Worker 89*d83cc019SAndroid Build Coastguard Workersub calibrate_nop 90*d83cc019SAndroid Build Coastguard Worker{ 91*d83cc019SAndroid Build Coastguard Worker my ($delay, $nop); 92*d83cc019SAndroid Build Coastguard Worker my $cmd = "$wsim"; 93*d83cc019SAndroid Build Coastguard Worker 94*d83cc019SAndroid Build Coastguard Worker show_cmd($cmd); 95*d83cc019SAndroid Build Coastguard Worker open WSIM, "$cmd |" or die; 96*d83cc019SAndroid Build Coastguard Worker while (<WSIM>) { 97*d83cc019SAndroid Build Coastguard Worker chomp; 98*d83cc019SAndroid Build Coastguard Worker if (/Nop calibration for (\d+)us delay is (\d+)./) { 99*d83cc019SAndroid Build Coastguard Worker $delay = $1; 100*d83cc019SAndroid Build Coastguard Worker $nop = $2; 101*d83cc019SAndroid Build Coastguard Worker } 102*d83cc019SAndroid Build Coastguard Worker 103*d83cc019SAndroid Build Coastguard Worker } 104*d83cc019SAndroid Build Coastguard Worker close WSIM; 105*d83cc019SAndroid Build Coastguard Worker 106*d83cc019SAndroid Build Coastguard Worker die unless $nop; 107*d83cc019SAndroid Build Coastguard Worker 108*d83cc019SAndroid Build Coastguard Worker return $nop 109*d83cc019SAndroid Build Coastguard Worker} 110*d83cc019SAndroid Build Coastguard Worker 111*d83cc019SAndroid Build Coastguard Workersub can_balance_workload 112*d83cc019SAndroid Build Coastguard Worker{ 113*d83cc019SAndroid Build Coastguard Worker my ($wrk) = @_; 114*d83cc019SAndroid Build Coastguard Worker my $res = 0; 115*d83cc019SAndroid Build Coastguard Worker 116*d83cc019SAndroid Build Coastguard Worker open WRK, "$wrk_root/$wrk" or die; 117*d83cc019SAndroid Build Coastguard Worker while (<WRK>) { 118*d83cc019SAndroid Build Coastguard Worker chomp; 119*d83cc019SAndroid Build Coastguard Worker if (/\.VCS\./) { 120*d83cc019SAndroid Build Coastguard Worker $res = 1; 121*d83cc019SAndroid Build Coastguard Worker last; 122*d83cc019SAndroid Build Coastguard Worker } 123*d83cc019SAndroid Build Coastguard Worker } 124*d83cc019SAndroid Build Coastguard Worker close WRK; 125*d83cc019SAndroid Build Coastguard Worker 126*d83cc019SAndroid Build Coastguard Worker return $res; 127*d83cc019SAndroid Build Coastguard Worker} 128*d83cc019SAndroid Build Coastguard Worker 129*d83cc019SAndroid Build Coastguard Workersub add_wps_arg 130*d83cc019SAndroid Build Coastguard Worker{ 131*d83cc019SAndroid Build Coastguard Worker my (@args) = @_; 132*d83cc019SAndroid Build Coastguard Worker my $period; 133*d83cc019SAndroid Build Coastguard Worker 134*d83cc019SAndroid Build Coastguard Worker return @args if $realtime_target <= 0; 135*d83cc019SAndroid Build Coastguard Worker 136*d83cc019SAndroid Build Coastguard Worker $period = int(1000000 / $realtime_target); 137*d83cc019SAndroid Build Coastguard Worker push @args, '-a'; 138*d83cc019SAndroid Build Coastguard Worker push @args, 'p.$period'; 139*d83cc019SAndroid Build Coastguard Worker 140*d83cc019SAndroid Build Coastguard Worker return @args; 141*d83cc019SAndroid Build Coastguard Worker} 142*d83cc019SAndroid Build Coastguard Worker 143*d83cc019SAndroid Build Coastguard Workersub run_workload 144*d83cc019SAndroid Build Coastguard Worker{ 145*d83cc019SAndroid Build Coastguard Worker my (@args) = @_; 146*d83cc019SAndroid Build Coastguard Worker my ($time, $wps, $cmd); 147*d83cc019SAndroid Build Coastguard Worker my @ret; 148*d83cc019SAndroid Build Coastguard Worker 149*d83cc019SAndroid Build Coastguard Worker @args = add_wps_arg(@args); 150*d83cc019SAndroid Build Coastguard Worker push @args, '-2' if $gt2; 151*d83cc019SAndroid Build Coastguard Worker 152*d83cc019SAndroid Build Coastguard Worker unshift @args, $wsim; 153*d83cc019SAndroid Build Coastguard Worker $cmd = join ' ', @args; 154*d83cc019SAndroid Build Coastguard Worker show_cmd($cmd); 155*d83cc019SAndroid Build Coastguard Worker 156*d83cc019SAndroid Build Coastguard Worker open WSIM, "$cmd |" or die; 157*d83cc019SAndroid Build Coastguard Worker while (<WSIM>) { 158*d83cc019SAndroid Build Coastguard Worker chomp; 159*d83cc019SAndroid Build Coastguard Worker if (/^(\d+\.\d+)s elapsed \((\d+\.?\d+) workloads\/s\)$/) { 160*d83cc019SAndroid Build Coastguard Worker $time = $1; 161*d83cc019SAndroid Build Coastguard Worker $wps = $2; 162*d83cc019SAndroid Build Coastguard Worker } elsif (/(\d+)\: \d+\.\d+s elapsed \(\d+ cycles, (\d+\.?\d+) workloads\/s\)/) { 163*d83cc019SAndroid Build Coastguard Worker $ret[$1] = $2; 164*d83cc019SAndroid Build Coastguard Worker } 165*d83cc019SAndroid Build Coastguard Worker } 166*d83cc019SAndroid Build Coastguard Worker close WSIM; 167*d83cc019SAndroid Build Coastguard Worker 168*d83cc019SAndroid Build Coastguard Worker return ($time, $wps, \@ret); 169*d83cc019SAndroid Build Coastguard Worker} 170*d83cc019SAndroid Build Coastguard Worker 171*d83cc019SAndroid Build Coastguard Workersub dump_cmd 172*d83cc019SAndroid Build Coastguard Worker{ 173*d83cc019SAndroid Build Coastguard Worker my ($cmd, $file) = @_; 174*d83cc019SAndroid Build Coastguard Worker 175*d83cc019SAndroid Build Coastguard Worker show_cmd("$cmd > $file"); 176*d83cc019SAndroid Build Coastguard Worker 177*d83cc019SAndroid Build Coastguard Worker open FOUT, '>', $file or die; 178*d83cc019SAndroid Build Coastguard Worker open TIN, "$cmd |" or die; 179*d83cc019SAndroid Build Coastguard Worker while (<TIN>) { 180*d83cc019SAndroid Build Coastguard Worker print FOUT $_; 181*d83cc019SAndroid Build Coastguard Worker } 182*d83cc019SAndroid Build Coastguard Worker close TIN; 183*d83cc019SAndroid Build Coastguard Worker close FOUT; 184*d83cc019SAndroid Build Coastguard Worker} 185*d83cc019SAndroid Build Coastguard Worker 186*d83cc019SAndroid Build Coastguard Workersub trace_workload 187*d83cc019SAndroid Build Coastguard Worker{ 188*d83cc019SAndroid Build Coastguard Worker my ($wrk, $b, $r, $c) = @_; 189*d83cc019SAndroid Build Coastguard Worker my @args = ($tracepl, '--trace', $wsim, '-q', '-n', $nop, '-r', $r, '-c', $c); 190*d83cc019SAndroid Build Coastguard Worker my $min_batches = 16 + $r * $c / 2; 191*d83cc019SAndroid Build Coastguard Worker my @skip_engine; 192*d83cc019SAndroid Build Coastguard Worker my %engines; 193*d83cc019SAndroid Build Coastguard Worker my ($cmd, $file); 194*d83cc019SAndroid Build Coastguard Worker 195*d83cc019SAndroid Build Coastguard Worker push @args, '-2' if $gt2; 196*d83cc019SAndroid Build Coastguard Worker 197*d83cc019SAndroid Build Coastguard Worker unless ($b eq '<none>') { 198*d83cc019SAndroid Build Coastguard Worker push @args, '-R'; 199*d83cc019SAndroid Build Coastguard Worker push @args, split /\s+/, $b; 200*d83cc019SAndroid Build Coastguard Worker } 201*d83cc019SAndroid Build Coastguard Worker 202*d83cc019SAndroid Build Coastguard Worker if (defined $w_direct) { 203*d83cc019SAndroid Build Coastguard Worker push @args, split /\s+/, $wrk; 204*d83cc019SAndroid Build Coastguard Worker } else { 205*d83cc019SAndroid Build Coastguard Worker push @args, '-w'; 206*d83cc019SAndroid Build Coastguard Worker push @args, $wrk_root . '/' . $wrk; 207*d83cc019SAndroid Build Coastguard Worker } 208*d83cc019SAndroid Build Coastguard Worker 209*d83cc019SAndroid Build Coastguard Worker show_cmd(join ' ', @args); 210*d83cc019SAndroid Build Coastguard Worker if (-e 'perf.data') { 211*d83cc019SAndroid Build Coastguard Worker unlink 'perf.data' or die; 212*d83cc019SAndroid Build Coastguard Worker } 213*d83cc019SAndroid Build Coastguard Worker system(@args) == 0 or die; 214*d83cc019SAndroid Build Coastguard Worker 215*d83cc019SAndroid Build Coastguard Worker $cmd = "perf script | $tracepl"; 216*d83cc019SAndroid Build Coastguard Worker show_cmd($cmd); 217*d83cc019SAndroid Build Coastguard Worker open CMD, "$cmd |" or die; 218*d83cc019SAndroid Build Coastguard Worker while (<CMD>) { 219*d83cc019SAndroid Build Coastguard Worker chomp; 220*d83cc019SAndroid Build Coastguard Worker if (/Ring(\S+): (\d+) batches.*?(\d+\.?\d+)% idle,/) { 221*d83cc019SAndroid Build Coastguard Worker if ($2 >= $min_batches) { 222*d83cc019SAndroid Build Coastguard Worker $engines{$1} = $3; 223*d83cc019SAndroid Build Coastguard Worker } else { 224*d83cc019SAndroid Build Coastguard Worker push @skip_engine, $1; 225*d83cc019SAndroid Build Coastguard Worker } 226*d83cc019SAndroid Build Coastguard Worker } elsif (/GPU: (\d+\.?\d+)% idle/) { 227*d83cc019SAndroid Build Coastguard Worker $engines{'gpu'} = $1; 228*d83cc019SAndroid Build Coastguard Worker } 229*d83cc019SAndroid Build Coastguard Worker } 230*d83cc019SAndroid Build Coastguard Worker close CMD; 231*d83cc019SAndroid Build Coastguard Worker 232*d83cc019SAndroid Build Coastguard Worker $wrk =~ s/$wrk_root//g; 233*d83cc019SAndroid Build Coastguard Worker $wrk =~ s/\.wsim//g; 234*d83cc019SAndroid Build Coastguard Worker $wrk =~ s/-w/W/g; 235*d83cc019SAndroid Build Coastguard Worker $wrk =~ s/[ -]/_/g; 236*d83cc019SAndroid Build Coastguard Worker $wrk =~ s/\//-/g; 237*d83cc019SAndroid Build Coastguard Worker $b =~ s/[ <>]/_/g; 238*d83cc019SAndroid Build Coastguard Worker $file = "${wrk}_${b}_-r${r}_-c${c}"; 239*d83cc019SAndroid Build Coastguard Worker 240*d83cc019SAndroid Build Coastguard Worker dump_cmd('perf script', "${file}.trace"); 241*d83cc019SAndroid Build Coastguard Worker 242*d83cc019SAndroid Build Coastguard Worker $cmd = "perf script | $tracepl --html -x ctxsave -s -c "; 243*d83cc019SAndroid Build Coastguard Worker $cmd .= join ' ', map("-i $_", @skip_engine); 244*d83cc019SAndroid Build Coastguard Worker 245*d83cc019SAndroid Build Coastguard Worker dump_cmd($cmd, "${file}.html"); 246*d83cc019SAndroid Build Coastguard Worker 247*d83cc019SAndroid Build Coastguard Worker return \%engines; 248*d83cc019SAndroid Build Coastguard Worker} 249*d83cc019SAndroid Build Coastguard Worker 250*d83cc019SAndroid Build Coastguard Workersub calibrate_workload 251*d83cc019SAndroid Build Coastguard Worker{ 252*d83cc019SAndroid Build Coastguard Worker my ($wrk) = @_; 253*d83cc019SAndroid Build Coastguard Worker my $tol = $tolerance; 254*d83cc019SAndroid Build Coastguard Worker my $loops = 0; 255*d83cc019SAndroid Build Coastguard Worker my $error; 256*d83cc019SAndroid Build Coastguard Worker my $r; 257*d83cc019SAndroid Build Coastguard Worker 258*d83cc019SAndroid Build Coastguard Worker $r = $realtime_target > 0 ? $realtime_target * $client_target_s : 23; 259*d83cc019SAndroid Build Coastguard Worker for (;;) { 260*d83cc019SAndroid Build Coastguard Worker my @args = ('-n', $nop, '-r', $r); 261*d83cc019SAndroid Build Coastguard Worker my ($time, $wps); 262*d83cc019SAndroid Build Coastguard Worker 263*d83cc019SAndroid Build Coastguard Worker if (defined $w_direct) { 264*d83cc019SAndroid Build Coastguard Worker push @args, split /\s+/, $wrk; 265*d83cc019SAndroid Build Coastguard Worker } else { 266*d83cc019SAndroid Build Coastguard Worker push @args, '-w'; 267*d83cc019SAndroid Build Coastguard Worker push @args, $wrk_root . '/' . $wrk; 268*d83cc019SAndroid Build Coastguard Worker } 269*d83cc019SAndroid Build Coastguard Worker 270*d83cc019SAndroid Build Coastguard Worker ($time, $wps) = run_workload(@args); 271*d83cc019SAndroid Build Coastguard Worker 272*d83cc019SAndroid Build Coastguard Worker $wps = $r / $time if $w_direct; 273*d83cc019SAndroid Build Coastguard Worker $error = abs($time - $client_target_s) / $client_target_s; 274*d83cc019SAndroid Build Coastguard Worker 275*d83cc019SAndroid Build Coastguard Worker last if $error <= $tol; 276*d83cc019SAndroid Build Coastguard Worker 277*d83cc019SAndroid Build Coastguard Worker $r = int($wps * $client_target_s); 278*d83cc019SAndroid Build Coastguard Worker $loops = $loops + 1; 279*d83cc019SAndroid Build Coastguard Worker if ($loops >= 3) { 280*d83cc019SAndroid Build Coastguard Worker $tol = $tol * (1.2 + ($tol)); 281*d83cc019SAndroid Build Coastguard Worker $loops = 0; 282*d83cc019SAndroid Build Coastguard Worker } 283*d83cc019SAndroid Build Coastguard Worker last if $tol > 0.2; 284*d83cc019SAndroid Build Coastguard Worker } 285*d83cc019SAndroid Build Coastguard Worker 286*d83cc019SAndroid Build Coastguard Worker return ($r, $error); 287*d83cc019SAndroid Build Coastguard Worker} 288*d83cc019SAndroid Build Coastguard Worker 289*d83cc019SAndroid Build Coastguard Workersub find_saturation_point 290*d83cc019SAndroid Build Coastguard Worker{ 291*d83cc019SAndroid Build Coastguard Worker my ($wrk, $rr, $verbose, @args) = @_; 292*d83cc019SAndroid Build Coastguard Worker my ($last_wps, $c, $swps, $wwps); 293*d83cc019SAndroid Build Coastguard Worker my $target = $realtime_target > 0 ? $realtime_target : $wps_target; 294*d83cc019SAndroid Build Coastguard Worker my $r = $rr; 295*d83cc019SAndroid Build Coastguard Worker my $wcnt; 296*d83cc019SAndroid Build Coastguard Worker my $maxc; 297*d83cc019SAndroid Build Coastguard Worker my $max = 0; 298*d83cc019SAndroid Build Coastguard Worker 299*d83cc019SAndroid Build Coastguard Worker push @args, '-v' if $multi_mode and $w_direct; 300*d83cc019SAndroid Build Coastguard Worker 301*d83cc019SAndroid Build Coastguard Worker if (defined $w_direct) { 302*d83cc019SAndroid Build Coastguard Worker push @args, split /\s+/, $wrk; 303*d83cc019SAndroid Build Coastguard Worker $wcnt = () = $wrk =~ /-[wW]/gi; 304*d83cc019SAndroid Build Coastguard Worker 305*d83cc019SAndroid Build Coastguard Worker } else { 306*d83cc019SAndroid Build Coastguard Worker push @args, '-w'; 307*d83cc019SAndroid Build Coastguard Worker push @args, $wrk_root . '/' . $wrk; 308*d83cc019SAndroid Build Coastguard Worker $wcnt = 1; 309*d83cc019SAndroid Build Coastguard Worker } 310*d83cc019SAndroid Build Coastguard Worker 311*d83cc019SAndroid Build Coastguard Worker for ($c = 1; ; $c = $c + 1) { 312*d83cc019SAndroid Build Coastguard Worker my ($time, $wps); 313*d83cc019SAndroid Build Coastguard Worker my @args_ = (@args, ('-r', $r, '-c', $c)); 314*d83cc019SAndroid Build Coastguard Worker 315*d83cc019SAndroid Build Coastguard Worker ($time, $wps, $wwps) = run_workload(@args_); 316*d83cc019SAndroid Build Coastguard Worker 317*d83cc019SAndroid Build Coastguard Worker say " $c clients is $wps wps." if $verbose; 318*d83cc019SAndroid Build Coastguard Worker 319*d83cc019SAndroid Build Coastguard Worker if ($c > 1) { 320*d83cc019SAndroid Build Coastguard Worker my $delta; 321*d83cc019SAndroid Build Coastguard Worker 322*d83cc019SAndroid Build Coastguard Worker if ($target <= 0) { 323*d83cc019SAndroid Build Coastguard Worker if ($wps > $max) { 324*d83cc019SAndroid Build Coastguard Worker $max = $wps; 325*d83cc019SAndroid Build Coastguard Worker $maxc = $c; 326*d83cc019SAndroid Build Coastguard Worker } 327*d83cc019SAndroid Build Coastguard Worker $delta = ($wps - $last_wps) / $last_wps; 328*d83cc019SAndroid Build Coastguard Worker if ($delta > 0) { 329*d83cc019SAndroid Build Coastguard Worker last if $delta < $tolerance; 330*d83cc019SAndroid Build Coastguard Worker } else { 331*d83cc019SAndroid Build Coastguard Worker $delta = ($wps - $max) / $max; 332*d83cc019SAndroid Build Coastguard Worker last if abs($delta) >= $tolerance; 333*d83cc019SAndroid Build Coastguard Worker } 334*d83cc019SAndroid Build Coastguard Worker } else { 335*d83cc019SAndroid Build Coastguard Worker $delta = ($wps / $c - $target) / $target; 336*d83cc019SAndroid Build Coastguard Worker last if $delta < 0 and abs($delta) >= $tolerance; 337*d83cc019SAndroid Build Coastguard Worker } 338*d83cc019SAndroid Build Coastguard Worker $r = int($rr * ($client_target_s / $time)); 339*d83cc019SAndroid Build Coastguard Worker } elsif ($c == 1) { 340*d83cc019SAndroid Build Coastguard Worker $swps = $wps; 341*d83cc019SAndroid Build Coastguard Worker return ($c, $wps, $swps, $wwps) if $wcnt > 1 or 342*d83cc019SAndroid Build Coastguard Worker $multi_mode or 343*d83cc019SAndroid Build Coastguard Worker ($wps_target_param < 0 and 344*d83cc019SAndroid Build Coastguard Worker $wps_target == 0); 345*d83cc019SAndroid Build Coastguard Worker } 346*d83cc019SAndroid Build Coastguard Worker 347*d83cc019SAndroid Build Coastguard Worker $last_wps = $wps; 348*d83cc019SAndroid Build Coastguard Worker } 349*d83cc019SAndroid Build Coastguard Worker 350*d83cc019SAndroid Build Coastguard Worker if ($target <= 0) { 351*d83cc019SAndroid Build Coastguard Worker return ($maxc, $max, $swps, $wwps); 352*d83cc019SAndroid Build Coastguard Worker } else { 353*d83cc019SAndroid Build Coastguard Worker return ($c - 1, $last_wps, $swps, $wwps); 354*d83cc019SAndroid Build Coastguard Worker } 355*d83cc019SAndroid Build Coastguard Worker} 356*d83cc019SAndroid Build Coastguard Worker 357*d83cc019SAndroid Build Coastguard Workergetopts('hv2xmn:b:W:B:r:t:i:R:T:w:', \%opts); 358*d83cc019SAndroid Build Coastguard Worker 359*d83cc019SAndroid Build Coastguard Workerif (defined $opts{'h'}) { 360*d83cc019SAndroid Build Coastguard Worker print <<ENDHELP; 361*d83cc019SAndroid Build Coastguard WorkerSupported options: 362*d83cc019SAndroid Build Coastguard Worker 363*d83cc019SAndroid Build Coastguard Worker -h Help text. 364*d83cc019SAndroid Build Coastguard Worker -v Be verbose. 365*d83cc019SAndroid Build Coastguard Worker -x Show external commands. 366*d83cc019SAndroid Build Coastguard Worker -2 Run gem_wsim in GT2 mode. 367*d83cc019SAndroid Build Coastguard Worker -n num Nop calibration. 368*d83cc019SAndroid Build Coastguard Worker -b str Balancer to pre-select. 369*d83cc019SAndroid Build Coastguard Worker Skips balancer auto-selection. 370*d83cc019SAndroid Build Coastguard Worker Passed straight the gem_wsim so use like -b "-b qd -R" 371*d83cc019SAndroid Build Coastguard Worker -W a,b,c Override the default list of workloads. 372*d83cc019SAndroid Build Coastguard Worker -B a,b,c Override the default list of balancers. 373*d83cc019SAndroid Build Coastguard Worker -r sec Target workload duration. 374*d83cc019SAndroid Build Coastguard Worker -t pct Calibration tolerance. 375*d83cc019SAndroid Build Coastguard Worker -i pct Engine idleness tolerance. 376*d83cc019SAndroid Build Coastguard Worker -R wps Run workloads in the real-time mode at wps rate. 377*d83cc019SAndroid Build Coastguard Worker -T wps Calibrate up to wps/client target instead of GPU saturation. 378*d83cc019SAndroid Build Coastguard Worker Negative values set the target based on the single client 379*d83cc019SAndroid Build Coastguard Worker performance where target = single-client-wps / -N. 380*d83cc019SAndroid Build Coastguard Worker -w str Pass-through to gem_wsim. Overrides normal workload selection. 381*d83cc019SAndroid Build Coastguard Worker -m Multi-workload mode. All selected workloads will be run in 382*d83cc019SAndroid Build Coastguard Worker parallel and overal score will be relative to when run 383*d83cc019SAndroid Build Coastguard Worker individually. 384*d83cc019SAndroid Build Coastguard WorkerENDHELP 385*d83cc019SAndroid Build Coastguard Worker exit 0; 386*d83cc019SAndroid Build Coastguard Worker} 387*d83cc019SAndroid Build Coastguard Worker 388*d83cc019SAndroid Build Coastguard Worker$verbose = 1 if defined $opts{'v'}; 389*d83cc019SAndroid Build Coastguard Worker$gt2 = 1 if defined $opts{'2'}; 390*d83cc019SAndroid Build Coastguard Worker$show_cmds = 1 if defined $opts{'x'}; 391*d83cc019SAndroid Build Coastguard Worker$multi_mode = 1 if defined $opts{'m'}; 392*d83cc019SAndroid Build Coastguard Workerif (defined $opts{'b'}) { 393*d83cc019SAndroid Build Coastguard Worker die unless substr($opts{'b'}, 0, 2) eq '-b'; 394*d83cc019SAndroid Build Coastguard Worker $balancer = $opts{'b'}; 395*d83cc019SAndroid Build Coastguard Worker} 396*d83cc019SAndroid Build Coastguard Workerif (defined $opts{'B'}) { 397*d83cc019SAndroid Build Coastguard Worker @balancers = split /,/, $opts{'B'}; 398*d83cc019SAndroid Build Coastguard Worker} else { 399*d83cc019SAndroid Build Coastguard Worker unshift @balancers, ''; 400*d83cc019SAndroid Build Coastguard Worker} 401*d83cc019SAndroid Build Coastguard Worker@workloads = split /,/, $opts{'W'} if defined $opts{'W'}; 402*d83cc019SAndroid Build Coastguard Worker$client_target_s = $opts{'r'} if defined $opts{'r'}; 403*d83cc019SAndroid Build Coastguard Worker$tolerance = $opts{'t'} / 100.0 if defined $opts{'t'}; 404*d83cc019SAndroid Build Coastguard Worker$idle_tolerance_pct = $opts{'i'} if defined $opts{'i'}; 405*d83cc019SAndroid Build Coastguard Worker$realtime_target = $opts{'R'} if defined $opts{'R'}; 406*d83cc019SAndroid Build Coastguard Worker$wps_target = $opts{'T'} if defined $opts{'T'}; 407*d83cc019SAndroid Build Coastguard Worker$wps_target_param = $wps_target; 408*d83cc019SAndroid Build Coastguard Worker$w_direct = $opts{'w'} if defined $opts{'w'}; 409*d83cc019SAndroid Build Coastguard Worker 410*d83cc019SAndroid Build Coastguard Workerif ($multi_mode) { 411*d83cc019SAndroid Build Coastguard Worker die if $w_direct; # Not supported 412*d83cc019SAndroid Build Coastguard Worker @multi_workloads = @workloads; 413*d83cc019SAndroid Build Coastguard Worker} 414*d83cc019SAndroid Build Coastguard Worker 415*d83cc019SAndroid Build Coastguard Worker@workloads = ($w_direct) if defined $w_direct; 416*d83cc019SAndroid Build Coastguard Worker 417*d83cc019SAndroid Build Coastguard Workersay "Workloads:"; 418*d83cc019SAndroid Build Coastguard Workerprint map { " $_\n" } @workloads; 419*d83cc019SAndroid Build Coastguard Workerprint "Balancers: "; 420*d83cc019SAndroid Build Coastguard Workersay map { "$_," } @balancers; 421*d83cc019SAndroid Build Coastguard Workersay "Target workload duration is ${client_target_s}s."; 422*d83cc019SAndroid Build Coastguard Workersay "Calibration tolerance is $tolerance."; 423*d83cc019SAndroid Build Coastguard Workersay "Real-time mode at ${realtime_target} wps." if $realtime_target > 0; 424*d83cc019SAndroid Build Coastguard Workersay "Wps target is ${wps_target} wps." if $wps_target > 0; 425*d83cc019SAndroid Build Coastguard Workersay "Multi-workload mode." if $multi_mode; 426*d83cc019SAndroid Build Coastguard Worker$nop = $opts{'n'}; 427*d83cc019SAndroid Build Coastguard Worker$nop = calibrate_nop() unless $nop; 428*d83cc019SAndroid Build Coastguard Workersay "Nop calibration is $nop."; 429*d83cc019SAndroid Build Coastguard Worker 430*d83cc019SAndroid Build Coastguard Workergoto VERIFY if defined $balancer; 431*d83cc019SAndroid Build Coastguard Worker 432*d83cc019SAndroid Build Coastguard Workermy (%best_bal, %best_bid); 433*d83cc019SAndroid Build Coastguard Workermy %results; 434*d83cc019SAndroid Build Coastguard Workermy %scores; 435*d83cc019SAndroid Build Coastguard Workermy %wscores; 436*d83cc019SAndroid Build Coastguard Workermy %cscores; 437*d83cc019SAndroid Build Coastguard Workermy %cwscores; 438*d83cc019SAndroid Build Coastguard Workermy %mscores; 439*d83cc019SAndroid Build Coastguard Workermy %mwscores; 440*d83cc019SAndroid Build Coastguard Worker 441*d83cc019SAndroid Build Coastguard Workersub add_points 442*d83cc019SAndroid Build Coastguard Worker{ 443*d83cc019SAndroid Build Coastguard Worker my ($wps, $scores, $wscores) = @_; 444*d83cc019SAndroid Build Coastguard Worker my ($min, $max, $spread); 445*d83cc019SAndroid Build Coastguard Worker my @sorted; 446*d83cc019SAndroid Build Coastguard Worker 447*d83cc019SAndroid Build Coastguard Worker @sorted = sort { $b <=> $a } values %{$wps}; 448*d83cc019SAndroid Build Coastguard Worker $max = $sorted[0]; 449*d83cc019SAndroid Build Coastguard Worker $min = $sorted[-1]; 450*d83cc019SAndroid Build Coastguard Worker $spread = $max - $min; 451*d83cc019SAndroid Build Coastguard Worker die if $spread < 0; 452*d83cc019SAndroid Build Coastguard Worker 453*d83cc019SAndroid Build Coastguard Worker foreach my $w (keys %{$wps}) { 454*d83cc019SAndroid Build Coastguard Worker my ($score, $wscore); 455*d83cc019SAndroid Build Coastguard Worker 456*d83cc019SAndroid Build Coastguard Worker unless (exists $scores->{$w}) { 457*d83cc019SAndroid Build Coastguard Worker $scores->{$w} = 0; 458*d83cc019SAndroid Build Coastguard Worker $wscores->{$w} = 0; 459*d83cc019SAndroid Build Coastguard Worker } 460*d83cc019SAndroid Build Coastguard Worker 461*d83cc019SAndroid Build Coastguard Worker $score = $wps->{$w} / $max; 462*d83cc019SAndroid Build Coastguard Worker $scores->{$w} = $scores->{$w} + $score; 463*d83cc019SAndroid Build Coastguard Worker $wscore = $score * $spread / $max; 464*d83cc019SAndroid Build Coastguard Worker $wscores->{$w} = $wscores->{$w} + $wscore; 465*d83cc019SAndroid Build Coastguard Worker } 466*d83cc019SAndroid Build Coastguard Worker} 467*d83cc019SAndroid Build Coastguard Worker 468*d83cc019SAndroid Build Coastguard Workermy @saturation_workloads = $multi_mode ? @multi_workloads : @workloads; 469*d83cc019SAndroid Build Coastguard Workermy %allwps; 470*d83cc019SAndroid Build Coastguard Workermy $widx = 0; 471*d83cc019SAndroid Build Coastguard Worker 472*d83cc019SAndroid Build Coastguard Workerpush @saturation_workloads, '-w ' . join ' -w ', map("$wrk_root/$_", @workloads) 473*d83cc019SAndroid Build Coastguard Worker if $multi_mode; 474*d83cc019SAndroid Build Coastguard Worker 475*d83cc019SAndroid Build Coastguard Workerforeach my $wrk (@saturation_workloads) { 476*d83cc019SAndroid Build Coastguard Worker my @args = ( "-n $nop"); 477*d83cc019SAndroid Build Coastguard Worker my ($r, $error, $should_b, $best); 478*d83cc019SAndroid Build Coastguard Worker my (%wps, %cwps, %mwps); 479*d83cc019SAndroid Build Coastguard Worker my @sorted; 480*d83cc019SAndroid Build Coastguard Worker my $range; 481*d83cc019SAndroid Build Coastguard Worker 482*d83cc019SAndroid Build Coastguard Worker $w_direct = $wrk if $multi_mode and $widx == $#saturation_workloads; 483*d83cc019SAndroid Build Coastguard Worker 484*d83cc019SAndroid Build Coastguard Worker $should_b = 1; 485*d83cc019SAndroid Build Coastguard Worker $should_b = can_balance_workload($wrk) unless defined $w_direct; 486*d83cc019SAndroid Build Coastguard Worker 487*d83cc019SAndroid Build Coastguard Worker print "\nEvaluating '$wrk'..."; 488*d83cc019SAndroid Build Coastguard Worker 489*d83cc019SAndroid Build Coastguard Worker ($r, $error) = calibrate_workload($wrk); 490*d83cc019SAndroid Build Coastguard Worker say " ${client_target_s}s is $r workloads. (error=$error)"; 491*d83cc019SAndroid Build Coastguard Worker 492*d83cc019SAndroid Build Coastguard Worker say " Finding saturation points for '$wrk'..."; 493*d83cc019SAndroid Build Coastguard Worker 494*d83cc019SAndroid Build Coastguard Worker BAL: foreach my $bal (@balancers) { 495*d83cc019SAndroid Build Coastguard Worker GBAL: foreach my $G ('', '-G', '-d', '-G -d') { 496*d83cc019SAndroid Build Coastguard Worker foreach my $H ('', '-H') { 497*d83cc019SAndroid Build Coastguard Worker my @xargs; 498*d83cc019SAndroid Build Coastguard Worker my ($w, $c, $s, $bwwps); 499*d83cc019SAndroid Build Coastguard Worker my $bid; 500*d83cc019SAndroid Build Coastguard Worker 501*d83cc019SAndroid Build Coastguard Worker if ($bal ne '') { 502*d83cc019SAndroid Build Coastguard Worker next GBAL if $G =~ '-G' and exists $bal_skip_G{$bal}; 503*d83cc019SAndroid Build Coastguard Worker 504*d83cc019SAndroid Build Coastguard Worker push @xargs, "-b $bal"; 505*d83cc019SAndroid Build Coastguard Worker push @xargs, '-R' unless exists $bal_skip_R{$bal}; 506*d83cc019SAndroid Build Coastguard Worker push @xargs, $G if $G ne ''; 507*d83cc019SAndroid Build Coastguard Worker push @xargs, $H if $H ne ''; 508*d83cc019SAndroid Build Coastguard Worker $bid = join ' ', @xargs; 509*d83cc019SAndroid Build Coastguard Worker print " $bal balancer ('$bid'): "; 510*d83cc019SAndroid Build Coastguard Worker } else { 511*d83cc019SAndroid Build Coastguard Worker $bid = '<none>'; 512*d83cc019SAndroid Build Coastguard Worker print " No balancing: "; 513*d83cc019SAndroid Build Coastguard Worker } 514*d83cc019SAndroid Build Coastguard Worker 515*d83cc019SAndroid Build Coastguard Worker $wps_target = 0 if $wps_target_param < 0; 516*d83cc019SAndroid Build Coastguard Worker 517*d83cc019SAndroid Build Coastguard Worker ($c, $w, $s, $bwwps) = 518*d83cc019SAndroid Build Coastguard Worker find_saturation_point($wrk, $r, 0, 519*d83cc019SAndroid Build Coastguard Worker (@args, @xargs)); 520*d83cc019SAndroid Build Coastguard Worker 521*d83cc019SAndroid Build Coastguard Worker if ($wps_target_param < 0) { 522*d83cc019SAndroid Build Coastguard Worker $wps_target = $s / -$wps_target_param; 523*d83cc019SAndroid Build Coastguard Worker 524*d83cc019SAndroid Build Coastguard Worker ($c, $w, $s, $bwwps) = 525*d83cc019SAndroid Build Coastguard Worker find_saturation_point($wrk, $r, 526*d83cc019SAndroid Build Coastguard Worker 0, 527*d83cc019SAndroid Build Coastguard Worker (@args, 528*d83cc019SAndroid Build Coastguard Worker @xargs)); 529*d83cc019SAndroid Build Coastguard Worker } 530*d83cc019SAndroid Build Coastguard Worker 531*d83cc019SAndroid Build Coastguard Worker if ($multi_mode and $w_direct) { 532*d83cc019SAndroid Build Coastguard Worker my $widx; 533*d83cc019SAndroid Build Coastguard Worker 534*d83cc019SAndroid Build Coastguard Worker die unless scalar(@multi_workloads) == 535*d83cc019SAndroid Build Coastguard Worker scalar(@{$bwwps}); 536*d83cc019SAndroid Build Coastguard Worker die unless scalar(@multi_workloads) == 537*d83cc019SAndroid Build Coastguard Worker scalar(keys %allwps); 538*d83cc019SAndroid Build Coastguard Worker 539*d83cc019SAndroid Build Coastguard Worker # Total of all workload wps from the 540*d83cc019SAndroid Build Coastguard Worker # mixed run. 541*d83cc019SAndroid Build Coastguard Worker $w = 0; 542*d83cc019SAndroid Build Coastguard Worker foreach $widx (0..$#{$bwwps}) { 543*d83cc019SAndroid Build Coastguard Worker $w += $bwwps->[$widx]; 544*d83cc019SAndroid Build Coastguard Worker } 545*d83cc019SAndroid Build Coastguard Worker 546*d83cc019SAndroid Build Coastguard Worker # Total of all workload wps from when 547*d83cc019SAndroid Build Coastguard Worker # ran individually with the best 548*d83cc019SAndroid Build Coastguard Worker # balancer. 549*d83cc019SAndroid Build Coastguard Worker my $tot = 0; 550*d83cc019SAndroid Build Coastguard Worker foreach my $wrk (@multi_workloads) { 551*d83cc019SAndroid Build Coastguard Worker $tot += $allwps{$wrk}->{$best_bid{$wrk}}; 552*d83cc019SAndroid Build Coastguard Worker } 553*d83cc019SAndroid Build Coastguard Worker 554*d83cc019SAndroid Build Coastguard Worker # Normalize mixed sum with sum of 555*d83cc019SAndroid Build Coastguard Worker # individual runs. 556*d83cc019SAndroid Build Coastguard Worker $w *= 100; 557*d83cc019SAndroid Build Coastguard Worker $w /= $tot; 558*d83cc019SAndroid Build Coastguard Worker 559*d83cc019SAndroid Build Coastguard Worker # Second metric is average of each 560*d83cc019SAndroid Build Coastguard Worker # workload wps normalized by their 561*d83cc019SAndroid Build Coastguard Worker # individual run performance with the 562*d83cc019SAndroid Build Coastguard Worker # best balancer. 563*d83cc019SAndroid Build Coastguard Worker $s = 0; 564*d83cc019SAndroid Build Coastguard Worker $widx = 0; 565*d83cc019SAndroid Build Coastguard Worker foreach my $wrk (@multi_workloads) { 566*d83cc019SAndroid Build Coastguard Worker $s += 100 * $bwwps->[$widx] / 567*d83cc019SAndroid Build Coastguard Worker $allwps{$wrk}->{$best_bid{$wrk}}; 568*d83cc019SAndroid Build Coastguard Worker $widx++; 569*d83cc019SAndroid Build Coastguard Worker } 570*d83cc019SAndroid Build Coastguard Worker $s /= scalar(@multi_workloads); 571*d83cc019SAndroid Build Coastguard Worker 572*d83cc019SAndroid Build Coastguard Worker say sprintf('Aggregate (normalized) %.2f%%; fairness %.2f%%', 573*d83cc019SAndroid Build Coastguard Worker $w, $s); 574*d83cc019SAndroid Build Coastguard Worker } else { 575*d83cc019SAndroid Build Coastguard Worker $allwps{$wrk} = \%wps; 576*d83cc019SAndroid Build Coastguard Worker } 577*d83cc019SAndroid Build Coastguard Worker 578*d83cc019SAndroid Build Coastguard Worker $wps{$bid} = $w; 579*d83cc019SAndroid Build Coastguard Worker $cwps{$bid} = $s; 580*d83cc019SAndroid Build Coastguard Worker 581*d83cc019SAndroid Build Coastguard Worker if ($realtime_target > 0 || $wps_target_param > 0) { 582*d83cc019SAndroid Build Coastguard Worker $mwps{$bid} = $w * $c; 583*d83cc019SAndroid Build Coastguard Worker } else { 584*d83cc019SAndroid Build Coastguard Worker $mwps{$bid} = $w + $s; 585*d83cc019SAndroid Build Coastguard Worker } 586*d83cc019SAndroid Build Coastguard Worker 587*d83cc019SAndroid Build Coastguard Worker say "$c clients ($w wps, $s wps single client, score=$mwps{$bid})." 588*d83cc019SAndroid Build Coastguard Worker unless $multi_mode and $w_direct; 589*d83cc019SAndroid Build Coastguard Worker 590*d83cc019SAndroid Build Coastguard Worker last BAL unless $should_b; 591*d83cc019SAndroid Build Coastguard Worker next BAL if $bal eq ''; 592*d83cc019SAndroid Build Coastguard Worker next GBAL if exists $bal_skip_H{$bal}; 593*d83cc019SAndroid Build Coastguard Worker } 594*d83cc019SAndroid Build Coastguard Worker } 595*d83cc019SAndroid Build Coastguard Worker } 596*d83cc019SAndroid Build Coastguard Worker 597*d83cc019SAndroid Build Coastguard Worker $widx++; 598*d83cc019SAndroid Build Coastguard Worker 599*d83cc019SAndroid Build Coastguard Worker @sorted = sort { $mwps{$b} <=> $mwps{$a} } keys %mwps; 600*d83cc019SAndroid Build Coastguard Worker $best_bid{$wrk} = $sorted[0]; 601*d83cc019SAndroid Build Coastguard Worker @sorted = sort { $b <=> $a } values %mwps; 602*d83cc019SAndroid Build Coastguard Worker $range = 1 - $sorted[-1] / $sorted[0]; 603*d83cc019SAndroid Build Coastguard Worker $best_bal{$wrk} = $sorted[0]; 604*d83cc019SAndroid Build Coastguard Worker 605*d83cc019SAndroid Build Coastguard Worker next if $multi_mode and not $w_direct; 606*d83cc019SAndroid Build Coastguard Worker 607*d83cc019SAndroid Build Coastguard Worker say " Best balancer is '$best_bid{$wrk}' (range=$range)."; 608*d83cc019SAndroid Build Coastguard Worker 609*d83cc019SAndroid Build Coastguard Worker 610*d83cc019SAndroid Build Coastguard Worker $results{$wrk} = \%mwps; 611*d83cc019SAndroid Build Coastguard Worker 612*d83cc019SAndroid Build Coastguard Worker add_points(\%wps, \%scores, \%wscores); 613*d83cc019SAndroid Build Coastguard Worker add_points(\%mwps, \%mscores, \%mwscores); 614*d83cc019SAndroid Build Coastguard Worker add_points(\%cwps, \%cscores, \%cwscores); 615*d83cc019SAndroid Build Coastguard Worker} 616*d83cc019SAndroid Build Coastguard Worker 617*d83cc019SAndroid Build Coastguard Workersub dump_scoreboard 618*d83cc019SAndroid Build Coastguard Worker{ 619*d83cc019SAndroid Build Coastguard Worker my ($n, $h) = @_; 620*d83cc019SAndroid Build Coastguard Worker my ($i, $str, $balancer); 621*d83cc019SAndroid Build Coastguard Worker my ($max, $range); 622*d83cc019SAndroid Build Coastguard Worker my @sorted; 623*d83cc019SAndroid Build Coastguard Worker 624*d83cc019SAndroid Build Coastguard Worker @sorted = sort { $b <=> $a } values %{$h}; 625*d83cc019SAndroid Build Coastguard Worker $max = $sorted[0]; 626*d83cc019SAndroid Build Coastguard Worker $range = 1 - $sorted[-1] / $max; 627*d83cc019SAndroid Build Coastguard Worker $str = "$n rank (range=$range):"; 628*d83cc019SAndroid Build Coastguard Worker say "\n$str"; 629*d83cc019SAndroid Build Coastguard Worker say '=' x length($str); 630*d83cc019SAndroid Build Coastguard Worker $i = 1; 631*d83cc019SAndroid Build Coastguard Worker foreach my $w (sort { $h->{$b} <=> $h->{$a} } keys %{$h}) { 632*d83cc019SAndroid Build Coastguard Worker my $score; 633*d83cc019SAndroid Build Coastguard Worker 634*d83cc019SAndroid Build Coastguard Worker $balancer = $w if $i == 1; 635*d83cc019SAndroid Build Coastguard Worker $score = $h->{$w} / $max; 636*d83cc019SAndroid Build Coastguard Worker 637*d83cc019SAndroid Build Coastguard Worker say " $i: '$w' ($score)"; 638*d83cc019SAndroid Build Coastguard Worker 639*d83cc019SAndroid Build Coastguard Worker $i = $i + 1; 640*d83cc019SAndroid Build Coastguard Worker } 641*d83cc019SAndroid Build Coastguard Worker 642*d83cc019SAndroid Build Coastguard Worker return $balancer; 643*d83cc019SAndroid Build Coastguard Worker} 644*d83cc019SAndroid Build Coastguard Worker 645*d83cc019SAndroid Build Coastguard Workerdump_scoreboard($multi_mode ? 'Throughput' : 'Total wps', \%scores); 646*d83cc019SAndroid Build Coastguard Workerdump_scoreboard('Total weighted wps', \%wscores) unless $multi_mode; 647*d83cc019SAndroid Build Coastguard Workerdump_scoreboard($multi_mode ? 'Fairness' : 'Per client wps', \%cscores); 648*d83cc019SAndroid Build Coastguard Workerdump_scoreboard('Per client weighted wps', \%cwscores) unless $multi_mode; 649*d83cc019SAndroid Build Coastguard Worker$balancer = dump_scoreboard($multi_mode ? 'Combined' : 'Combined wps', \%mscores); 650*d83cc019SAndroid Build Coastguard Worker$balancer = dump_scoreboard('Combined weighted wps', \%mwscores) unless $multi_mode; 651*d83cc019SAndroid Build Coastguard Worker 652*d83cc019SAndroid Build Coastguard WorkerVERIFY: 653*d83cc019SAndroid Build Coastguard Worker 654*d83cc019SAndroid Build Coastguard Workermy %problem_wrk; 655*d83cc019SAndroid Build Coastguard Worker 656*d83cc019SAndroid Build Coastguard Workerdie unless defined $balancer; 657*d83cc019SAndroid Build Coastguard Worker 658*d83cc019SAndroid Build Coastguard Workersay "\nBalancer is '$balancer'."; 659*d83cc019SAndroid Build Coastguard Workersay "Idleness tolerance is $idle_tolerance_pct%."; 660*d83cc019SAndroid Build Coastguard Worker 661*d83cc019SAndroid Build Coastguard Workerif ($multi_mode) { 662*d83cc019SAndroid Build Coastguard Worker $w_direct = '-w ' . join ' -w ', map("$wrk_root/$_", @workloads); 663*d83cc019SAndroid Build Coastguard Worker @workloads = ($w_direct); 664*d83cc019SAndroid Build Coastguard Worker} 665*d83cc019SAndroid Build Coastguard Worker 666*d83cc019SAndroid Build Coastguard Workerforeach my $wrk (@workloads) { 667*d83cc019SAndroid Build Coastguard Worker my @args = ( "-n $nop" ); 668*d83cc019SAndroid Build Coastguard Worker my ($r, $error, $c, $wps, $swps); 669*d83cc019SAndroid Build Coastguard Worker my $saturated = 0; 670*d83cc019SAndroid Build Coastguard Worker my $result = 'Pass'; 671*d83cc019SAndroid Build Coastguard Worker my $vcs2 = $gt2 ? '1:0' : '2:1'; 672*d83cc019SAndroid Build Coastguard Worker my %problem; 673*d83cc019SAndroid Build Coastguard Worker my $engines; 674*d83cc019SAndroid Build Coastguard Worker 675*d83cc019SAndroid Build Coastguard Worker next if not defined $w_direct and not can_balance_workload($wrk); 676*d83cc019SAndroid Build Coastguard Worker 677*d83cc019SAndroid Build Coastguard Worker push @args, $balancer unless $balancer eq '<none>'; 678*d83cc019SAndroid Build Coastguard Worker 679*d83cc019SAndroid Build Coastguard Worker if (scalar(keys %results)) { 680*d83cc019SAndroid Build Coastguard Worker $r = $results{$wrk}->{$balancer} / $best_bal{$wrk} * 100.0; 681*d83cc019SAndroid Build Coastguard Worker } else { 682*d83cc019SAndroid Build Coastguard Worker $r = '---'; 683*d83cc019SAndroid Build Coastguard Worker } 684*d83cc019SAndroid Build Coastguard Worker say " \nProfiling '$wrk' ($r% of best)..."; 685*d83cc019SAndroid Build Coastguard Worker 686*d83cc019SAndroid Build Coastguard Worker ($r, $error) = calibrate_workload($wrk); 687*d83cc019SAndroid Build Coastguard Worker say " ${client_target_s}s is $r workloads. (error=$error)"; 688*d83cc019SAndroid Build Coastguard Worker 689*d83cc019SAndroid Build Coastguard Worker ($c, $wps, $swps) = find_saturation_point($wrk, $r, $verbose, @args); 690*d83cc019SAndroid Build Coastguard Worker say " Saturation at $c clients ($wps workloads/s)."; 691*d83cc019SAndroid Build Coastguard Worker push @args, "-c $c"; 692*d83cc019SAndroid Build Coastguard Worker 693*d83cc019SAndroid Build Coastguard Worker $engines = trace_workload($wrk, $balancer, $r, $c); 694*d83cc019SAndroid Build Coastguard Worker 695*d83cc019SAndroid Build Coastguard Worker foreach my $key (keys %{$engines}) { 696*d83cc019SAndroid Build Coastguard Worker next if $key eq 'gpu'; 697*d83cc019SAndroid Build Coastguard Worker $saturated = $saturated + 1 698*d83cc019SAndroid Build Coastguard Worker if $engines->{$key} < $idle_tolerance_pct; 699*d83cc019SAndroid Build Coastguard Worker } 700*d83cc019SAndroid Build Coastguard Worker 701*d83cc019SAndroid Build Coastguard Worker if ($saturated == 0) { 702*d83cc019SAndroid Build Coastguard Worker # Not a single saturated engine 703*d83cc019SAndroid Build Coastguard Worker $result = 'FAIL'; 704*d83cc019SAndroid Build Coastguard Worker } elsif (not exists $engines->{'2:0'} or not exists $engines->{$vcs2}) { 705*d83cc019SAndroid Build Coastguard Worker # VCS1 and VCS2 not present in a balancing workload 706*d83cc019SAndroid Build Coastguard Worker $result = 'FAIL'; 707*d83cc019SAndroid Build Coastguard Worker } elsif ($saturated == 1 and 708*d83cc019SAndroid Build Coastguard Worker ($engines->{'2:0'} < $idle_tolerance_pct or 709*d83cc019SAndroid Build Coastguard Worker $engines->{$vcs2} < $idle_tolerance_pct)) { 710*d83cc019SAndroid Build Coastguard Worker # Only one VCS saturated 711*d83cc019SAndroid Build Coastguard Worker $result = 'WARN'; 712*d83cc019SAndroid Build Coastguard Worker } 713*d83cc019SAndroid Build Coastguard Worker 714*d83cc019SAndroid Build Coastguard Worker $result = 'WARN' if $engines->{'gpu'} > $idle_tolerance_pct; 715*d83cc019SAndroid Build Coastguard Worker 716*d83cc019SAndroid Build Coastguard Worker if ($result ne 'Pass') { 717*d83cc019SAndroid Build Coastguard Worker $problem{'c'} = $c; 718*d83cc019SAndroid Build Coastguard Worker $problem{'r'} = $r; 719*d83cc019SAndroid Build Coastguard Worker $problem{'stats'} = $engines; 720*d83cc019SAndroid Build Coastguard Worker $problem_wrk{$wrk} = \%problem; 721*d83cc019SAndroid Build Coastguard Worker } 722*d83cc019SAndroid Build Coastguard Worker 723*d83cc019SAndroid Build Coastguard Worker print " $result ["; 724*d83cc019SAndroid Build Coastguard Worker print map " $_: $engines->{$_}%,", sort keys %{$engines}; 725*d83cc019SAndroid Build Coastguard Worker say " ]"; 726*d83cc019SAndroid Build Coastguard Worker} 727*d83cc019SAndroid Build Coastguard Worker 728*d83cc019SAndroid Build Coastguard Workersay "\nProblematic workloads were:" if scalar(keys %problem_wrk) > 0; 729*d83cc019SAndroid Build Coastguard Workerforeach my $wrk (sort keys %problem_wrk) { 730*d83cc019SAndroid Build Coastguard Worker my $problem = $problem_wrk{$wrk}; 731*d83cc019SAndroid Build Coastguard Worker 732*d83cc019SAndroid Build Coastguard Worker print " $wrk -c $problem->{'c'} -r $problem->{'r'} ["; 733*d83cc019SAndroid Build Coastguard Worker print map " $_: $problem->{'stats'}->{$_}%,", 734*d83cc019SAndroid Build Coastguard Worker sort keys %{$problem->{'stats'}}; 735*d83cc019SAndroid Build Coastguard Worker say " ]"; 736*d83cc019SAndroid Build Coastguard Worker} 737