Home | History | Annotate | Download | only in tests
      1 # This script filters the PERF traces based on the specified parameters and
      2 # measures the rate of the filtered traces.  This can be used to measure
      3 # video encode/decode/preview frame rates.
      4 # 
      5 # Fields in a PERF CSV line:
      6 #
      7 # $1 - time stamp
      8 # $2 - PID
      9 # $3 - address
     10 # $4 - component
     11 # $5-$10 - domains (AD, VD, ID, AE, VE, IE)
     12 # $11 - component type
     13 # $12 - operation
     14 # $13-... operation specific arguments:
     15 #    Buffer:
     16 # $13 - sending|received|xfering
     17 # $14 - frame|buffer
     18 # $15 - from
     19 # $16 - to
     20 # $17 - size
     21 # $18 - address 1
     22 # $19 - address 2
     23 #    Boundary:
     24 # $13 - hex
     25 # $14 - textual
     26 
     27 # initialize variables
     28 BEGIN {
     29    FS = ",";                         # reading a CSV file
     30 
     31    what = what ? what : "frame";     # what buffers are we looking at
     32    how  = how  ? how  : "sending";   # what is the operation
     33    to   = to   ? to   : "";          # who are the recipients of these buffers
     34    from = from ? from : "";          # who are the senders of these buffers
     35 
     36    # boundary - only log buffer traces in the steady state of this component
     37    boundary = boundary ? boundary : "****";
     38 
     39    min  = (size != "") ? (size) : (min != "") ? (min) : 1;   # min size of buffers to watch
     40    max  = (size != "") ? (size) : (max != "") ? (max) : 5e9; # max size of buffers to watch
     41    # Additional variables not set:
     42 
     43    # debug    - debug flag
     44    # after    - only measure frames after the specified #
     45    # who      - who is logging these buffer transfers
     46 
     47    # get variable assignments from ARGV
     48    for (i=1; i<ARGC; i++) {
     49       arg = ARGV[i];
     50       if      (gsub("^what=",    "",arg)) { what     = arg }
     51       else if (gsub("^to=",      "",arg)) { to       = arg }
     52       else if (gsub("^from=",    "",arg)) { from     = arg }
     53       else if (gsub("^how=",     "",arg)) { how      = arg }
     54       else if (gsub("^who=",     "",arg)) { who      = arg }
     55       else if (gsub("^boundary=","",arg)) { boundary = arg }
     56       else if (gsub("^after=",   "",arg)) { after    = arg }
     57       else if (gsub("^debug=",   "",arg)) { debug    = arg }
     58       else if (gsub("^size=",    "",arg)) { min = max = (arg) }
     59       else if (gsub("^min=",     "",arg)) { min      = (arg) }
     60       else if (gsub("^max=",     "",arg)) { max      = (arg) }
     61 
     62       else continue;
     63       delete ARGV[i];
     64    }
     65 
     66    if (!who) {
     67       print "Must specify component to observe";
     68       exit 1;
     69    }
     70 
     71    # we are using the component thread as boundary by default
     72    if (boundary == "****") {
     73       if (substr(who, 0, 3) == "VP_" ||
     74           substr(who, 0, 3) == "VD_" ||
     75           substr(who, 0, 3) == "VE_" ||
     76           substr(who, 0, 3) == "CAM") {
     77          boundary = substr(who, 0, 3) "T";
     78       }
     79    }
     80 
     81    after++;   # we always have to after the 1st time stamp to get a time delta
     82    skip = after + 1;
     83 
     84    # start counting unless boundary is set, in which case
     85    count = boundary ? skip : 0;
     86 
     87    # initialize counters
     88    x = xx = N = 0;
     89    x_no_pause = xx_no_pause = N_no_pause = 0;
     90 
     91    if (debug > 1) {
     92       print "who = ", who
     93       print "how = ", how
     94       print "what = ", what
     95       print "from = ", (from ? from : "UNDEFINED")
     96       print "to = ", (to ? to : "UNDEFINED")
     97       print "min = ", min
     98       print "max = ", max
     99    }
    100 
    101    # convert to decimal
    102    min = min + 0
    103    max = max + 0
    104 }
    105 
    106 # Check for non-CSV trace file
    107 /^</ {
    108    print "ERROR: non-CSV file encountered.  Please use csv = 1 in ./perf.ini";
    109    exit;
    110 }
    111 
    112 # Count frames
    113 #   frames start with a number, with operation "Buffer"
    114 /^[0-9]/ && $4 == who && $12 == "Buffer" &&
    115 #   how and what has to match
    116 #   if from or to are specified they also have to match
    117 $13 == how && $14 == what && (!from || ($15 == from)) && (!to || ($16 == to)) &&
    118 #   size has to fall in the range specified, we have to add 0 because of a
    119 #   rare rounding issue in AWK when comparing hex and decimal numbers
    120 ((0 + $17) >= min) &&
    121 ((0 + $17) <= max) {
    122    # debug
    123    if (debug) { print $0 }
    124 
    125    # increase the count from the boundary
    126    if (count == after) {
    127       delta = $1 - last;
    128       if (delta >= 2) {
    129          print "Warning: Found a pause of", delta, "seconds";
    130       }
    131       else
    132       {
    133          x_no_pause  += delta;
    134          xx_no_pause += delta * delta;
    135          N_no_pause++;
    136       }
    137       x  += delta;
    138       xx += delta * delta;
    139       N++;
    140    }
    141    if (count < after) { count++; }
    142    last = $1;
    143 }
    144 
    145 # Check boundaries
    146 /Steady/ && $12 == "Boundary" && $4 == boundary {
    147    # debug
    148    if (debug) { print $0 }
    149 
    150    # start counting if starting steady state, skip counting if ending steady
    151    # state
    152    count = /started/ ? 0 : skip;
    153 }
    154 
    155 END {
    156    # calculate inverse (1/x) average and variance
    157    if (N) {
    158       x /= N;
    159       xx /= N;
    160       s = xx ? (x * x / xx) : 0;
    161       result = 1/x " fps (s=" s ") (from " N " data points)";
    162       print "Rate is", result;
    163 
    164       if (N != N_no_pause) {
    165          if (N_no_pause) {
    166             x = x_no_pause / N_no_pause;
    167             xx = xx_no_pause / N_no_pause;
    168             s = xx ? (x * x / xx) : 1;
    169             result = 1/x " fps (s=" s ") (from " N " data points)";
    170             print "(Adjusted rate without pauses is", result, ")";
    171          } else {
    172             print "(Not enough data to calculate adjusted rate without pauses)";
    173          }
    174       }
    175    } else {
    176       print "Error:   Not enough data to calculate rate";
    177    }
    178 }
    179 
    180