stats.py revision 1318:57d49cdb92a5
1#!/usr/bin/env python
2from __future__ import division
3import re, sys, math
4
5def usage():
6    print '''\
7Usage: %s [-E] [-F] [-d <db> ] [-g <get> ] [-h <host>] [-p]
8       [-s <system>] [-r <runs> ] [-u <username>] <command> [command args]
9''' % sys.argv[0]
10    sys.exit(1)
11
12def getopts(list, flags):
13    import getopt
14    try:
15        opts, args = getopt.getopt(list, flags)
16    except getopt.GetoptError:
17        usage()
18
19    return opts, args
20
21def printval(name, value, invert = False):
22    if invert and value != 0.0:
23        value = 1 / value
24
25    if value == (1e300*1e300):
26        return
27
28    if printval.mode == 'G':
29        print '%s:    %g' % (name, value)
30    elif printval.mode != 'F' and value > 1e6:
31        print '%s:    %0.5e' % (name, value)
32    else:
33        print '%s:    %f' % (name, value)
34
35printval.mode = 'G'
36
37def unique(list):
38    set = {}
39    map(set.__setitem__, list, [])
40    return set.keys()
41
42def graphdata68(runs, options, tag, label, value):
43    import info
44    configs = ['ste', 'hte', 'htd', 'ocm', 'occ', 'ocp' ]
45    benchmarks = [ 'm', 's', 'snt', 'nb1', 'w1', 'w2', 'w3', 'w4', 'nm', 'ns', 'nw1', 'nw2', 'nw3' ]
46    dmas = [ 'x' ]
47    caches = [ '2', '4' ]
48
49    names = []
50
51    bench_system = {
52        'm' : 'client',
53        's' : 'client',
54        'snt' : 'client',
55        'nb1' : 'server',
56        'nb2' : 'server',
57        'nt1' : 'server',
58        'nt2' : 'server',
59        'w1' : 'server',
60        'w2' : 'server',
61        'w3' : 'server',
62        'w4' : 'server',
63        'w1s' : 'server',
64        'w2s' : 'server',
65        'w3s' : 'server',
66        'ns' : 'natbox',
67        'nm' : 'natbox',
68        'nw1' : 'natbox',
69        'nw2' : 'natbox',
70        'nw3' : 'natbox'
71        }
72
73    for bench in benchmarks:
74        if bench_system[bench] != options.system:
75            continue
76
77        for dma in dmas:
78            for cache in caches:
79                    names.append([bench, dma, cache])
80
81    for bench,dma,cache in names:
82        base = '%s.%s.%s' % (bench, dma, cache)
83        fname = 'data/%s.%s.68.dat' % (tag, base)
84        f = open(fname, 'w')
85        print >>f, '#set TITLE = '
86        print >>f, '#set ylbl = %s' % label
87        #print >>f, '#set sublabels = %s' % ' '.join(configs)
88        print >>f, '#set sublabels = ste hte htd ocm occ ocs'
89
90        for speed,freq in zip(['s', '6', '8', 'q'],['4GHz', '6GHz','8GHz', '10GHz']):
91            print >>f, '"%s"' % freq,
92            for conf in configs:
93                name = '%s.%s.%s.%s.%s' % (conf, bench, dma, cache, speed)
94                run = info.source.allRunNames[name]
95                info.display_run = run.run;
96                val = float(value)
97                if val == 1e300*1e300:
98                    print >>f, 0.0,
99                else:
100                    print >>f, "%f" % val,
101            print >>f
102        f.close()
103
104def graphdata(runs, options, tag, label, value):
105    if options.graph68:
106        graphdata68(runs, options, tag, label, value)
107        return
108
109    import info
110    configs = ['ste', 'hte', 'htd', 'ocm', 'occ', 'ocp' ]
111    #benchmarks = [ 'm', 's', 'nb1', 'nb2', 'nt1', 'nt2', 'w1', 'w2', 'w3', 'w4', 'ns', 'nm', 'nw1', 'nw2', 'nw3' ]
112    #benchmarks = [ 'm', 's', 'nb1', 'nb2', 'nt1', 'w1', 'w2', 'w3', 'ns', 'nm', 'w1s' ]
113    benchmarks = [ 'm', 's', 'nb1', 'nb2', 'w1', 'w2', 'w3', 'w4', 'ns', 'nm', 'nw1', 'snt' ]
114    #dmas = [ 'x', 'd', 'b' ]
115    dmas = [ 'x' ]
116    caches = [ '2', '4' ]
117
118    names = []
119
120    bench_system = {
121        'm' : 'client',
122        's' : 'client',
123        'snt' : 'client',
124        'nb1' : 'server',
125        'nb2' : 'server',
126        'nt1' : 'server',
127        'nt2' : 'server',
128        'w1' : 'server',
129        'w2' : 'server',
130        'w3' : 'server',
131        'w4' : 'server',
132        'w1s' : 'server',
133        'w2s' : 'server',
134        'w3s' : 'server',
135        'ns' : 'natbox',
136        'nm' : 'natbox',
137        'nw1' : 'natbox',
138        'nw2' : 'natbox',
139        'nw3' : 'natbox'
140        }
141
142    for bench in benchmarks:
143        if bench_system[bench] != options.system:
144            continue
145
146        for dma in dmas:
147            for cache in caches:
148                    names.append([bench, dma, cache])
149
150    for bench,dma,cache in names:
151        base = '%s.%s.%s' % (bench, dma, cache)
152        fname = 'data/%s.%s.dat' % (tag, base)
153        f = open(fname, 'w')
154        print >>f, '#set TITLE = '
155        print >>f, '#set ylbl = %s' % label
156        #print >>f, '#set sublabels = %s' % ' '.join(configs)
157        print >>f, '#set sublabels = ste hte htd ocm occ ocs'
158
159        for speed,freq in zip(['s', 'q'],['4GHz','10GHz']):
160            print >>f, '"%s"' % freq,
161            for conf in configs:
162                name = '%s.%s.%s.%s.%s' % (conf, bench, dma, cache, speed)
163                run = info.source.allRunNames[name]
164                info.display_run = run.run;
165                val = float(value)
166                if val == 1e300*1e300:
167                    print >>f, 0.0,
168                else:
169                    print >>f, "%f" % val,
170            print >>f
171        f.close()
172
173def printdata(runs, value, invert = False):
174    import info
175    for run in runs:
176        info.display_run = run.run;
177        val = float(value)
178        printval(run.name, val)
179
180class CommandException(Exception):
181    pass
182
183def commands(options, command, args):
184    if command == 'database':
185        if len(args) == 0: raise CommandException
186
187        import dbinit
188        mydb = dbinit.MyDB(options)
189
190        if args[0] == 'drop':
191            if len(args) > 2: raise CommandException
192            mydb.admin()
193            mydb.drop()
194            if len(args) == 2 and args[1] == 'init':
195                mydb.create()
196                mydb.connect()
197                mydb.populate()
198            mydb.close()
199            return
200
201        if args[0] == 'init':
202            if len(args) > 1: raise CommandException
203            mydb.admin()
204            mydb.create()
205            mydb.connect()
206            mydb.populate()
207            mydb.close()
208            return
209
210        if args[0] == 'clean':
211            if len(args) > 1: raise CommandException
212            mydb.connect()
213            mydb.clean()
214            return
215
216        raise CommandException
217
218    import db, info
219    info.source = db.Database()
220    info.source.host = options.host
221    info.source.db = options.db
222    info.source.passwd = options.passwd
223    info.source.user = options.user
224    info.source.connect()
225    info.source.update_dict(globals())
226
227    if type(options.get) is str:
228        info.source.get = options.get
229
230    if options.runs is None:
231        runs = info.source.allRuns
232    else:
233        rx = re.compile(options.runs)
234        runs = []
235        for run in info.source.allRuns:
236            if rx.match(run.name):
237                runs.append(run)
238
239    info.display_run = runs[0].run
240
241    if command == 'runs':
242        user = None
243        opts, args = getopts(args, '-u')
244        if len(args):
245            raise CommandException
246        for o,a in opts:
247            if o == '-u':
248                user = a
249        info.source.listRuns(user)
250        return
251
252    if command == 'stability':
253        stats = info.source.getStat(args[0])
254        info.source.get = "avg"
255
256        #loop through all the stats selected
257        for stat in stats:
258
259            print "%s:" % stat.name
260            print "%-30s %12s %12s %4s %5s %5s %5s" % \
261                  ("run name", "average", "stdev", ">10%", ">1SDV", ">2SDV", "SAMP")
262            print "%-30s %12s %12s %4s %5s %5s %5s" % \
263                  ("------------------------------", "------------",
264                   "------------", "----", "-----", "-----", "-----")
265            #loop through all the selected runs
266            for run in runs:
267                info.display_run = run.run;
268                runTicks = info.source.retTicks([ run ])
269                #throw away the first one, it's 0
270                runTicks.pop(0)
271                stat.ticks = runTicks
272                avg = float(stat)
273                stdev = 0
274                numoutsideavg  = 0
275                numoutside1std = 0
276                numoutside2std = 0
277
278                #loop through all the various ticks for each run
279                for tick in runTicks:
280                    stat.ticks = str(tick)
281                    val = float(stat)
282                    if (val < (avg * .9)) or (val > (avg * 1.1)):
283                        numoutsideavg += 1
284                    stdev += pow((val-avg),2)
285
286                stdev = math.sqrt(stdev / len(runTicks))
287                for tick in runTicks:
288                    stat.ticks = str(tick)
289                    val = float(stat)
290                    if (val < (avg - stdev)) or (val > (avg + stdev)):
291                        numoutside1std += 1
292                    if (val < (avg - (2*stdev))) or (val > (avg + (2*stdev))):
293                        numoutside2std += 1
294
295                print "%-30s %12s %12s %4s %5s %5s %5s" % \
296                      (run.name, "%.1f" % avg, "%.1f" % stdev,
297                       "%d" % numoutsideavg, "%d" % numoutside1std,
298                       "%d" % numoutside2std, "%d" % len(runTicks))
299        return
300
301
302    if command == 'stats':
303        if len(args) == 0:
304            info.source.listStats()
305        elif len(args) == 1:
306            info.source.listStats(args[0])
307        else:
308            raise CommandException
309
310        return
311
312    if command == 'stat':
313        if len(args) != 1:
314            raise CommandException
315
316        stats = info.source.getStat(args[0])
317        for stat in stats:
318            if options.graph:
319                graphdata(runs, options, stat.name, stat.name, stat)
320            else:
321                if options.ticks:
322                   print 'only displaying sample %s' % options.ticks
323                   stat.ticks = options.ticks
324
325                if options.binned:
326                    print 'kernel ticks'
327                    stat.bins = 'kernel'
328                    printdata(runs, stat)
329
330                    print 'idle ticks'
331                    stat.bins = 'idle'
332                    printdata(runs, stat)
333
334                    print 'user ticks'
335                    stat.bins = 'user'
336                    printdata(runs, stat)
337
338                    print 'interrupt ticks'
339                    stat.bins = 'interrupt'
340                    printdata(runs, stat)
341
342                    print 'total ticks'
343
344                stat.bins = None
345                print stat.name
346                printdata(runs, stat)
347        return
348
349    if command == 'formula':
350        if len(args) != 1:
351            raise CommandException
352
353        stats = eval(args[0])
354        for stat in stats:
355            if options.graph:
356                graphdata(runs, options, stat.name, stat.name, stat)
357            else:
358                if options.binned:
359                    print 'kernel ticks'
360                    stat.bins = 'kernel'
361                    printdata(runs, stat)
362
363                    print 'idle ticks'
364                    stat.bins = 'idle'
365                    printdata(runs, stat)
366
367                    print 'user ticks'
368                    stat.bins = 'user'
369                    printdata(runs, stat)
370
371                    print 'interrupt ticks'
372                    stat.bins = 'interrupt'
373                    printdata(runs, stat)
374
375                    print 'total ticks'
376
377                stat.bins = None
378                print args[0]
379                printdata(runs, stat)
380        return
381
382    if command == 'bins':
383        if len(args) == 0:
384            info.source.listBins()
385        elif len(args) == 1:
386            info.source.listBins(args[0])
387        else:
388            raise CommandException
389
390        return
391
392    if command == 'formulas':
393        if len(args) == 0:
394            info.source.listFormulas()
395        elif len(args) == 1:
396            info.source.listFormulas(args[0])
397        else:
398            raise CommandException
399
400        return
401
402    if command == 'samples':
403        if len(args):
404            raise CommandException
405
406        info.source.listTicks(runs)
407        return
408
409    if len(args):
410        raise CommandException
411
412    system = info.source.__dict__[options.system]
413
414    if command == 'usertime':
415        import copy
416        kernel = copy.copy(system.full_cpu.numCycles)
417        kernel.bins = 'kernel'
418
419        user = copy.copy(system.full_cpu.numCycles)
420        user.bins = 'user'
421
422        if options.graph:
423            graphdata(runs, options, 'usertime', 'User Fraction',
424                      user / system.full_cpu.numCycles)
425        else:
426            printdata(runs, user / system.full_cpu.numCycles)
427        return
428
429    if command == 'ticks':
430        if options.binned:
431            print 'kernel ticks'
432            system.full_cpu.numCycles.bins = 'kernel'
433            printdata(runs, system.full_cpu.numCycles)
434
435            print 'idle ticks'
436            system.full_cpu.numCycles.bins = 'idle'
437            printdata(runs, system.full_cpu.numCycles)
438
439            print 'user ticks'
440            system.full_cpu.numCycles.bins = 'user'
441            printdata(runs, system.full_cpu.numCycles)
442
443            print 'total ticks'
444
445        system.full_cpu.numCycles.bins = None
446        printdata(runs, system.full_cpu.numCycles)
447        return
448
449    if command == 'packets':
450        packets = system.tsunami.etherdev.rxPackets
451        if options.graph:
452            graphdata(runs, options, 'packets', 'Packets', packets)
453        else:
454            printdata(runs, packets)
455        return
456
457    if command == 'ppt' or command == 'tpp':
458        ppt = system.tsunami.etherdev.rxPackets / sim_ticks
459        printdata(runs, ppt, command == 'tpp')
460        return
461
462    if command == 'pps':
463        pps = system.tsunami.etherdev.rxPackets / sim_seconds
464        if options.graph:
465            graphdata(runs, options, 'pps', 'Packets/s', pps)
466        else:
467            printdata(runs, pps)
468        return
469
470    if command == 'bpt' or command == 'tpb':
471        bytes = system.tsunami.etherdev.rxBytes + system.tsunami.etherdev.txBytes
472        bpt = bytes / sim_ticks * 8
473        if options.graph:
474            graphdata(runs, options, 'bpt', 'bps / Hz', bpt)
475        else:
476            printdata(runs, bpt, command == 'tpb')
477        return
478
479    if command == 'bptb' or command == 'tpbb':
480        bytes = system.tsunami.etherdev.rxBytes + system.tsunami.etherdev.txBytes
481
482        print 'kernel stats'
483        bytes.bins = 'kernel'
484        printdata(runs, bytes / ticks)
485
486        print 'idle stats'
487        bytes.bins = 'idle'
488        printdata(runs, bytes / ticks)
489
490        print 'user stats'
491        bytes.bins = 'user'
492        printdata(runs, bytes / ticks)
493
494        return
495
496    if command == 'bytes':
497        stat = system.tsunami.etherdev.rxBytes + system.tsunami.etherdev.txBytes
498
499        if options.binned:
500            print '%s kernel stats' % stat.name
501            stat.bins = 'kernel'
502            printdata(runs, stat)
503
504            print '%s idle stats' % stat.name
505            stat.bins = 'idle'
506            printdata(runs, stat)
507
508            print '%s user stats' % stat.name
509            stat.bins = 'user'
510            printdata(runs, stat)
511
512            print '%s total stats' % stat.name
513            stat.bins = None
514
515        printdata(runs, stat)
516        return
517
518    if command == 'rxbps':
519        gbps = system.tsunami.etherdev.rxBandwidth / 1e9
520        if options.graph:
521            graphdata(runs, options, 'rxbps', 'Bandwidth (Gbps)',  gbps)
522        else:
523            printdata(runs, gbps)
524        return
525
526    if command == 'txbps':
527        gbps = system.tsunami.etherdev.txBandwidth / 1e9
528        if options.graph:
529            graphdata(runs, options, 'txbps', 'Bandwidth (Gbps)',  gbps)
530        else:
531            printdata(runs, gbps)
532        return
533
534    if command == 'bps':
535        rxbps = system.tsunami.etherdev.rxBandwidth
536        txbps = system.tsunami.etherdev.txBandwidth
537        gbps = (rxbps + txbps) / 1e9
538        if options.graph:
539            graphdata(runs, options, 'bps', 'Bandwidth (Gbps)',  gbps)
540        else:
541            printdata(runs, gbps)
542        return
543
544    if command == 'misses':
545        stat = system.L2.overall_mshr_misses
546        if options.binned:
547            print '%s kernel stats' % stat.name
548            stat.bins = 'kernel'
549            printdata(runs, stat)
550
551            print '%s idle stats' % stat.name
552            stat.bins = 'idle'
553            printdata(runs, stat)
554
555            print '%s user stats' % stat.name
556            stat.bins = 'user'
557            printdata(runs, stat)
558
559            print '%s total stats' % stat.name
560
561        stat.bins = None
562        if options.graph:
563            graphdata(runs, options, 'misses', 'Overall MSHR Misses', stat)
564        else:
565            printdata(runs, stat)
566        return
567
568    if command == 'mpkb':
569        misses = system.L2.overall_mshr_misses
570        rxbytes = system.tsunami.etherdev.rxBytes
571        txbytes = system.tsunami.etherdev.txBytes
572
573        if options.binned:
574            print 'mpkb kernel stats'
575            misses.bins = 'kernel'
576            mpkb = misses / ((rxbytes + txbytes) / 1024)
577            printdata(runs, mpkb)
578
579            print 'mpkb idle stats'
580            misses.bins = 'idle'
581            mpkb = misses / ((rxbytes + txbytes) / 1024)
582            printdata(runs, mpkb)
583
584            print 'mpkb user stats'
585            misses.bins = 'user'
586            mpkb = misses / ((rxbytes + txbytes) / 1024)
587            printdata(runs, mpkb)
588
589            print 'mpkb total stats'
590
591        mpkb = misses / ((rxbytes + txbytes) / 1024)
592        misses.bins = None
593        if options.graph:
594            graphdata(runs, options, 'mpkb', 'Misses / KB',  mpkb)
595        else:
596            printdata(runs, mpkb)
597        return
598
599    if command == 'ipkb':
600        interrupts = system.full_cpu.kern.faults[4]
601        rxbytes = system.tsunami.etherdev.rxBytes
602        txbytes = system.tsunami.etherdev.txBytes
603
604        if options.binned:
605            print 'ipkb kernel stats'
606            interrupts.bins = 'kernel'
607            ipkb = interrupts / ((rxbytes + txbytes) / 1024)
608            printdata(runs, ipkb)
609
610            print 'ipkb idle stats'
611            interrupts.bins = 'idle'
612            ipkb = interrupts / ((rxbytes + txbytes) / 1024)
613            printdata(runs, ipkb)
614
615            print 'ipkb user stats'
616            interrupts.bins = 'user'
617            ipkb = interrupts / ((rxbytes + txbytes) / 1024)
618            printdata(runs, ipkb)
619
620            print 'ipkb total stats'
621
622        ipkb = interrupts / ((rxbytes + txbytes) / 1024)
623        interrupts.bins = None
624        if options.graph:
625            graphdata(runs, options, 'ipkb', 'Interrupts / KB',  ipkb)
626        else:
627            printdata(runs, ipkb)
628        return
629
630    if command == 'execute':
631        printdata(runs, system.full_cpu.ISSUE__count)
632        return
633
634    if command == 'commit':
635        printdata(runs, system.full_cpu.COM__count)
636        return
637
638    if command == 'fetch':
639        printdata(runs, system.full_cpu.FETCH__count)
640        return
641
642    if command == 'bpp':
643        ed = system.tsunami.etherdev
644        bpp = (ed.rxBytes + ed.txBytes) / (ed.rxPackets + ed.txPackets)
645        if options.graph:
646            graphdata(runs, options, 'bpp', 'Bytes / Packet',  bpp)
647        else:
648            printdata(runs, bpp)
649        return
650
651    if command == 'rxbpp':
652        bpp = system.tsunami.etherdev.rxBytes / system.tsunami.etherdev.rxPackets
653        if options.graph:
654            graphdata(runs, options, 'rxbpp', 'Receive Bytes / Packet',  bpp)
655        else:
656            printdata(runs, bpp)
657        return
658
659    if command == 'txbpp':
660        bpp = system.tsunami.etherdev.txBytes / system.tsunami.etherdev.txPackets
661        if options.graph:
662            graphdata(runs, options, 'txbpp', 'Transmit Bytes / Packet',  bpp)
663        else:
664            printdata(runs, bpp)
665        return
666
667    if command == 'rtp':
668        rtp = system.tsunami.etherdev.rxPackets / system.tsunami.etherdev.txPackets
669        if options.graph:
670            graphdata(runs, options, 'rtp', 'rxPackets / txPackets',  rtp)
671        else:
672            printdata(runs, rtp)
673        return
674
675    if command == 'rtb':
676        rtb = system.tsunami.etherdev.rxBytes / system.tsunami.etherdev.txBytes
677        if options.graph:
678            graphdata(runs, options, 'rtb', 'rxBytes / txBytes',  rtb)
679        else:
680            printdata(runs, rtb)
681        return
682
683    raise CommandException
684
685
686class Options: pass
687
688if __name__ == '__main__':
689    import getpass
690
691    options = Options()
692    options.host = 'zizzer.pool'
693    options.db = None
694    options.passwd = ''
695    options.user = getpass.getuser()
696    options.runs = None
697    options.system = 'client'
698    options.get = None
699    options.binned = False
700    options.graph = False
701    options.graph68 = False
702    options.ticks = False
703
704    opts, args = getopts(sys.argv[1:], '-6BEFGd:g:h:pr:s:u:T:')
705    for o,a in opts:
706        if o == '-6':
707            options.graph68 = True
708        if o == '-B':
709            options.binned = True
710        if o == '-E':
711            printval.mode = 'E'
712        if o == '-F':
713            printval.mode = 'F'
714        if o == '-G':
715            options.graph = True;
716        if o == '-d':
717            options.db = a
718        if o == '-g':
719            options.get = a
720        if o == '-h':
721            options.host = a
722        if o == '-p':
723            options.passwd = getpass.getpass()
724        if o == '-r':
725            options.runs = a
726        if o == '-u':
727            options.user = a
728        if o == '-s':
729            options.system = a
730        if o == '-T':
731            options.ticks = a
732
733    if len(args) == 0:
734        usage()
735
736    command = args[0]
737    args = args[1:]
738
739    try:
740        commands(options, command, args)
741    except CommandException:
742        usage()
743