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