1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
|
# qstats.stp: Queue statistics gathering tapset
# ------------------------------------------------------------------------
# The default timing function: microseconds. This function could
# go into a separate file (say, qstats_qs_time.stp), so that a user
# script can override it with another definition.
function qs_time () { return gettimeofday_us () }
# ------------------------------------------------------------------------
global qs_wtime, qs_wlentime, qs_wcount
global qs_rtime, qs_rlentime, qs_rcount
global qs_stime, qs_utime, qs_dcount
# ------------------------------------------------------------------------
function _qs_update (qname) {
now = qs_time ()
then = qs_utime[qname]; if (! then) { then = now }
delta = now-then
qs_wtime[qname] += qs_wcount[qname] ? delta : 0
qs_wlentime[qname] += qs_wcount[qname] * delta
qs_rtime[qname] += qs_rcount[qname] ? delta : 0
qs_rlentime[qname] += qs_rcount[qname] * delta
qs_utime[qname] = now
}
function qs_wait (qname) { # enqueueing request
_qs_update (qname)
qs_wcount[qname] ++
}
function qs_run (qname) { # starting to service request
_qs_update (qname)
if (qs_wcount[qname] > 0) {
qs_wcount[qname] --
qs_rcount[qname] ++
}
}
function qs_done (qname) { # done servicing request
_qs_update (qname)
if (qs_rcount[qname] > 0) {
qs_rcount[qname] --
qs_dcount[qname] ++
}
}
# ------------------------------------------------------------------------
function qsq_start (qname) { # reset statistics for new baseline
qs_rcount[qname] = 0
delete qs_rtime[qname]
delete qs_rlentime[qname]
qs_wcount[qname] = 0
delete qs_wtime[qname]
delete qs_wlentime[qname]
delete qs_dcount[qname]
delete qs_utime[qname]
qs_stime[qname] = qs_time ()
}
# ------------------------------------------------------------------------
# Various query functions. Each returns the average, taken over the time
# interval from the last qsq_start(). Most deal with fractions, and so
# also take a scale parameter (use 100 for percent).
# fraction of time that any request was being serviced
function qsq_utilization (qname, scale) {
_qs_update (qname)
elapsed = qs_time() - qs_stime[qname]
return (scale * qs_rtime[qname]) / elapsed
}
# fraction of time that any request was blocked in the wait queue
function qsq_blocked (qname, scale) {
_qs_update (qname)
elapsed = qs_time() - qs_stime[qname]
return (scale * qs_wtime[qname]) / elapsed
}
# length of wait queue
function qsq_wait_queue_length (qname, scale) {
_qs_update (qname)
elapsed = qs_time() - qs_stime[qname]
return (scale * qs_wlentime[qname]) / elapsed
}
# service time (amount of time per request service)
function qsq_service_time (qname, scale) {
_qs_update (qname)
return (scale * qs_rlentime[qname]) / qs_dcount[qname]
}
# wait time (amount of time in queue + service per request)
function qsq_wait_time (qname, scale) {
_qs_update (qname)
return (scale * (qs_rlentime[qname] + qs_wlentime[qname]))
/ qs_dcount[qname]
}
# service rate (number of requests served per unit time)
function qsq_throughput (qname, scale) {
_qs_update (qname)
elapsed = qs_time() - qs_stime[qname]
return (scale * qs_dcount[qname]) / elapsed
}
# ------------------------------------------------------------------------
function qsq_print (qname) {
qt = qsq_throughput (qname, 1000000000) # 1000 * (number of requests served per second)
qwl = qsq_wait_queue_length (qname, 1000)
printf("%s: %d.%03d ops/s, %d.%03d qlen, %d await, %d svctm, %d%% wait, %d%% util\n",
qname,
qt/1000, qt%1000,
qwl/1000, qwl%1000,
qsq_wait_time (qname, 1),
qsq_service_time (qname, 1),
qsq_blocked (qname, 100),
qsq_utilization (qname, 100))
}
|